vagrant-windows-hyperv 1.0.2 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +34 -0
- data/README.md +22 -11
- data/lib/vagrant-windows-hyperv.rb +4 -1
- data/lib/vagrant-windows-hyperv/action.rb +0 -19
- data/lib/vagrant-windows-hyperv/communication/powershell.rb +7 -3
- data/lib/vagrant-windows-hyperv/errors.rb +20 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/action.rb +45 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/action/customize.rb +167 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/action/import.rb +72 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/action/provision.rb +5 -1
- data/lib/vagrant-windows-hyperv/monkey_patch/config.rb +51 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/driver.rb +52 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/machine.rb +3 -3
- data/lib/vagrant-windows-hyperv/monkey_patch/plugins/synced_folders/smb/synced_folders.rb +3 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/scripts/add_switch_to_vm.ps1 +38 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/scripts/create_switch.ps1 +75 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/scripts/find_vm_switch_name.ps1 +29 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/scripts/get_adapters.ps1 +17 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/scripts/import_vm.ps1 +136 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/scripts/switch_exist.ps1 +54 -0
- data/lib/vagrant-windows-hyperv/monkey_patch/scripts/utils/write_messages.ps1 +20 -0
- data/lib/vagrant-windows-hyperv/provisioner/puppet.rb +2 -2
- data/lib/vagrant-windows-hyperv/scripts/check_winrm.ps1 +7 -3
- data/lib/vagrant-windows-hyperv/scripts/upload_file.ps1 +29 -3
- data/lib/vagrant-windows-hyperv/scripts/utils/create_session.ps1 +19 -5
- data/lib/vagrant-windows-hyperv/version.rb +1 -1
- data/locales/en.yml +60 -3
- metadata +15 -3
- data/lib/vagrant-windows-hyperv/monkey_patch/util/powershell.rb +0 -37
@@ -11,7 +11,11 @@ module Vagrant
|
|
11
11
|
class Provision
|
12
12
|
|
13
13
|
alias_method :original_run_provisioner, :run_provisioner
|
14
|
-
# Override this method from core vagrant, here we branch out the
|
14
|
+
# Override this method from core vagrant, here we branch out the
|
15
|
+
# provision for windows
|
16
|
+
# FIXME:
|
17
|
+
# This should be removed when the core vagrant supports communication
|
18
|
+
# class for windows guests
|
15
19
|
def run_provisioner(env)
|
16
20
|
if env[:machine].config.vm.guest == :windows
|
17
21
|
case env[:provisioner].class.to_s
|
@@ -0,0 +1,51 @@
|
|
1
|
+
#-------------------------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
+
# All Rights Reserved. Licensed under the MIT License.
|
4
|
+
#--------------------------------------------------------------------------
|
5
|
+
|
6
|
+
require "vagrant"
|
7
|
+
|
8
|
+
module VagrantPlugins
|
9
|
+
module HyperV
|
10
|
+
class Config < Vagrant.plugin("2", :config)
|
11
|
+
# The timeout to wait for an IP address when booting the machine,
|
12
|
+
# in seconds.
|
13
|
+
#
|
14
|
+
# @return [Integer]
|
15
|
+
attr_accessor :ip_address_timeout
|
16
|
+
attr_reader :customizations
|
17
|
+
|
18
|
+
def initialize
|
19
|
+
@ip_address_timeout = UNSET_VALUE
|
20
|
+
@customizations = []
|
21
|
+
end
|
22
|
+
|
23
|
+
def customize(*command)
|
24
|
+
@customizations ||= []
|
25
|
+
event = command.first.is_a?(String) ? command.shift : "pre-boot"
|
26
|
+
command = command[0]
|
27
|
+
options = command[1]
|
28
|
+
@customizations << [event, command, options]
|
29
|
+
end
|
30
|
+
|
31
|
+
def finalize!
|
32
|
+
if @ip_address_timeout == UNSET_VALUE
|
33
|
+
@ip_address_timeout = 120
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate(machine)
|
38
|
+
errors = _detected_errors
|
39
|
+
|
40
|
+
valid_events = ["pre-boot"]
|
41
|
+
@customizations.each do |event, _|
|
42
|
+
if !valid_events.include?(event)
|
43
|
+
errors << "Invalid custom event #{event} use pre-boot"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
{ "Hyper-V" => errors }
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#-------------------------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
+
# All Rights Reserved. Licensed under the Apache 2.0 License.
|
4
|
+
#--------------------------------------------------------------------------
|
5
|
+
|
6
|
+
require "#{Vagrant::source_root}/plugins/providers/hyperv/driver"
|
7
|
+
|
8
|
+
module VagrantPlugins
|
9
|
+
module HyperV
|
10
|
+
class Driver
|
11
|
+
|
12
|
+
# Override the existing import method to Override the import_vm.ps1 script
|
13
|
+
def import(options)
|
14
|
+
load_path = Pathname.new(File.expand_path("../scripts", __FILE__))
|
15
|
+
script_path = load_path.join('import_vm.ps1').to_s
|
16
|
+
execute(script_path, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
# New methods for network customization
|
20
|
+
def create_network_switch(options)
|
21
|
+
load_path = Pathname.new(File.expand_path("../scripts", __FILE__))
|
22
|
+
script_path = load_path.join('create_switch.ps1')
|
23
|
+
execute(script_path, options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def list_net_adapters
|
27
|
+
load_path = Pathname.new(File.expand_path("../scripts", __FILE__))
|
28
|
+
script_path = load_path.join('get_adapters.ps1')
|
29
|
+
execute(script_path, {})
|
30
|
+
end
|
31
|
+
|
32
|
+
def find_vm_switch_name
|
33
|
+
load_path = Pathname.new(File.expand_path("../scripts", __FILE__))
|
34
|
+
script_path = load_path.join('find_vm_switch_name.ps1')
|
35
|
+
execute(script_path, {vm_id: vm_id})
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_swith_to_vm(options)
|
39
|
+
load_path = Pathname.new(File.expand_path("../scripts", __FILE__))
|
40
|
+
script_path = load_path.join('add_switch_to_vm.ps1')
|
41
|
+
execute(script_path, options)
|
42
|
+
end
|
43
|
+
|
44
|
+
def switch_exist(options)
|
45
|
+
load_path = Pathname.new(File.expand_path("../scripts", __FILE__))
|
46
|
+
script_path = load_path.join('switch_exist.ps1')
|
47
|
+
execute(script_path, options)
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -6,14 +6,14 @@
|
|
6
6
|
module Vagrant
|
7
7
|
class Machine
|
8
8
|
|
9
|
-
|
9
|
+
ssh_communicate = instance_method(:communicate)
|
10
10
|
|
11
|
-
|
11
|
+
define_method(:communicate) do
|
12
12
|
unless @communicator
|
13
13
|
if @config.vm.guest == :windows
|
14
14
|
@communicator = VagrantPlugins::VagrantHyperV::Communicator::PowerShell.new(self)
|
15
15
|
else
|
16
|
-
@communicator =
|
16
|
+
@communicator = ssh_communicate.bind(self).()
|
17
17
|
end
|
18
18
|
end
|
19
19
|
@communicator
|
@@ -11,6 +11,9 @@ module VagrantPlugins
|
|
11
11
|
|
12
12
|
alias_method :original_enable, :enable
|
13
13
|
|
14
|
+
# FIXME:
|
15
|
+
# This is a workaround to enable the guest VM to access the SMB share
|
16
|
+
# set in the host.
|
14
17
|
def enable(machine, folders, nfsopts)
|
15
18
|
response = machine.provider.driver.get_host_ip
|
16
19
|
host_ip = response["host_ip"]
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#-------------------------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
+
# All Rights Reserved. Licensed under the MIT License.
|
4
|
+
#--------------------------------------------------------------------------
|
5
|
+
|
6
|
+
param (
|
7
|
+
[Parameter(Mandatory=$true)]
|
8
|
+
[string]$type,
|
9
|
+
[Parameter(Mandatory=$true)]
|
10
|
+
[string]$name,
|
11
|
+
[Parameter(Mandatory=$true)]
|
12
|
+
[string]$vm_id,
|
13
|
+
[Parameter(Mandatory=$false)]
|
14
|
+
[string]$adapter
|
15
|
+
)
|
16
|
+
|
17
|
+
# Include the following modules
|
18
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
19
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
20
|
+
|
21
|
+
try {
|
22
|
+
|
23
|
+
$vm = Get-VM -Id $vm_id -ErrorAction "stop"
|
24
|
+
Get-VMSwitch "$name" | Where-Object { $_.SwitchType -eq "$type" } `
|
25
|
+
| Connect-VMNetworkAdapter -VMName $vm.Name
|
26
|
+
|
27
|
+
$resultHash = @{
|
28
|
+
message = "OK"
|
29
|
+
}
|
30
|
+
Write-Output-Message $(ConvertTo-JSON $resultHash)
|
31
|
+
}
|
32
|
+
catch {
|
33
|
+
$errortHash = @{
|
34
|
+
type = "PowerShellError"
|
35
|
+
error = "$_"
|
36
|
+
}
|
37
|
+
Write-Error-Message $(ConvertTo-JSON $errortHash)
|
38
|
+
}
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#-------------------------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
+
# All Rights Reserved. Licensed under the MIT License.
|
4
|
+
#--------------------------------------------------------------------------
|
5
|
+
|
6
|
+
param (
|
7
|
+
[Parameter(Mandatory=$true)]
|
8
|
+
[string]$type,
|
9
|
+
[Parameter(Mandatory=$true)]
|
10
|
+
[string]$name,
|
11
|
+
[Parameter(Mandatory=$true)]
|
12
|
+
[string]$vm_id,
|
13
|
+
[Parameter(Mandatory=$true)]
|
14
|
+
[string]$adapter
|
15
|
+
)
|
16
|
+
|
17
|
+
# Include the following modules
|
18
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
19
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
20
|
+
|
21
|
+
try {
|
22
|
+
|
23
|
+
# Find the current IP address of the host. This will be used later to test the
|
24
|
+
# network connectivity upon creating a new switch to a network adapter
|
25
|
+
$ip = (Get-WmiObject -class win32_NetworkAdapterConfiguration -Filter 'ipenabled = "true"').ipaddress[0]
|
26
|
+
|
27
|
+
$max_attempts = 5
|
28
|
+
$operation_pass = $false
|
29
|
+
do {
|
30
|
+
try {
|
31
|
+
if ($type -eq "external") {
|
32
|
+
New-VMSwitch -Name "$name" -NetAdapterName $adapter -ErrorAction "stop"
|
33
|
+
}
|
34
|
+
$operation_pass = $true
|
35
|
+
} catch {
|
36
|
+
$max_attempts = $max_attempts - 1
|
37
|
+
sleep 5
|
38
|
+
}
|
39
|
+
}
|
40
|
+
while (!$operation_pass -and $max_attempts -gt 0)
|
41
|
+
|
42
|
+
# On creating a new switch / a new network adapter, there are chances that
|
43
|
+
# the network may get disconnected for a while.
|
44
|
+
|
45
|
+
# Keep checking for network availability before exiting this script
|
46
|
+
$max_attempts = 10
|
47
|
+
$network_available = $false
|
48
|
+
do {
|
49
|
+
try {
|
50
|
+
$ping_response = Test-Connection "$ip" -ErrorAction "stop"
|
51
|
+
$network_available = $true
|
52
|
+
} catch {
|
53
|
+
$max_attempts = $max_attempts - 1
|
54
|
+
sleep 5
|
55
|
+
}
|
56
|
+
}
|
57
|
+
while (!$network_available -and $max_attempts -gt 0)
|
58
|
+
if (-not $network_available) {
|
59
|
+
$resptHash = @{
|
60
|
+
message = "Network down"
|
61
|
+
}
|
62
|
+
} else {
|
63
|
+
$resptHash = @{
|
64
|
+
message = "Success"
|
65
|
+
}
|
66
|
+
}
|
67
|
+
Write-Output-Message $(ConvertTo-JSON $resptHash)
|
68
|
+
return
|
69
|
+
} catch {
|
70
|
+
$errortHash = @{
|
71
|
+
type = "PowerShellError"
|
72
|
+
error = "$_"
|
73
|
+
}
|
74
|
+
Write-Error-Message $(ConvertTo-JSON $errortHash)
|
75
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#-------------------------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
+
# All Rights Reserved. Licensed under the MIT License.
|
4
|
+
#--------------------------------------------------------------------------
|
5
|
+
|
6
|
+
param (
|
7
|
+
[Parameter(Mandatory=$true)]
|
8
|
+
[string]$vm_id
|
9
|
+
)
|
10
|
+
|
11
|
+
# Include the following modules
|
12
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
13
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
14
|
+
|
15
|
+
|
16
|
+
try {
|
17
|
+
$vm = Get-VM -Id $vm_id -ErrorAction "stop"
|
18
|
+
$network_adapter = Get-VMNetworkAdapter -vm $vm
|
19
|
+
$resultHash = @{}
|
20
|
+
$resultHash["switch_name"] = $network_adapter.SwitchName
|
21
|
+
$resultHash["network_adapter"] = $network_adapter.Name
|
22
|
+
Write-Output-Message $(ConvertTo-JSON $resultHash)
|
23
|
+
} catch [Microsoft.HyperV.PowerShell.VirtualizationOperationFailedException] {
|
24
|
+
$errortHash = @{
|
25
|
+
type = "PowerShellError"
|
26
|
+
error = "$_"
|
27
|
+
}
|
28
|
+
Write-Error-Message $(ConvertTo-JSON $errortHash)
|
29
|
+
}
|
@@ -0,0 +1,17 @@
|
|
1
|
+
#-------------------------------------------------------------------------
|
2
|
+
# Copyright (c) Microsoft Open Technologies, Inc.
|
3
|
+
# All Rights Reserved. Licensed under the MIT License.
|
4
|
+
#--------------------------------------------------------------------------
|
5
|
+
# Include the following modules
|
6
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
7
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
8
|
+
|
9
|
+
$adapters = @()
|
10
|
+
|
11
|
+
Get-NetAdapter `
|
12
|
+
| Select-Object Name,InterfaceDescription,Status `
|
13
|
+
| Where-Object {$_.Status-eq "up"} `
|
14
|
+
| ForEach-Object -Process {
|
15
|
+
$adapters += $_
|
16
|
+
}
|
17
|
+
Write-Output-Message $(ConvertTo-JSON $adapters)
|
@@ -0,0 +1,136 @@
|
|
1
|
+
Param(
|
2
|
+
[Parameter(Mandatory=$true)]
|
3
|
+
[string]$vm_xml_config,
|
4
|
+
[Parameter(Mandatory=$true)]
|
5
|
+
[string]$vhdx_path
|
6
|
+
)
|
7
|
+
|
8
|
+
# Include the following modules
|
9
|
+
$Dir = Split-Path $script:MyInvocation.MyCommand.Path
|
10
|
+
. ([System.IO.Path]::Combine($Dir, "utils\write_messages.ps1"))
|
11
|
+
|
12
|
+
[xml]$vmconfig = Get-Content -Path $vm_xml_config
|
13
|
+
|
14
|
+
$vm_name = $vmconfig.configuration.properties.name.'#text'
|
15
|
+
$processors = $vmconfig.configuration.settings.processors.count.'#text'
|
16
|
+
|
17
|
+
function GetUniqueName($name) {
|
18
|
+
Get-VM | ForEach-Object -Process {
|
19
|
+
if ($name -eq $_.Name) {
|
20
|
+
$name = $name + "_1"
|
21
|
+
}
|
22
|
+
}
|
23
|
+
return $name
|
24
|
+
}
|
25
|
+
|
26
|
+
do {
|
27
|
+
$name = $vm_name
|
28
|
+
$vm_name = GetUniqueName $name
|
29
|
+
} while ($vm_name -ne $name)
|
30
|
+
|
31
|
+
$memory = (Select-Xml -xml $vmconfig -XPath "//memory").node.Bank
|
32
|
+
if ($memory.dynamic_memory_enabled."#text" -eq "True") {
|
33
|
+
$dynamicmemory = $True
|
34
|
+
}
|
35
|
+
else {
|
36
|
+
$dynamicmemory = $False
|
37
|
+
}
|
38
|
+
|
39
|
+
# Memory values need to be in bytes
|
40
|
+
$MemoryMaximumBytes = ($memory.limit."#text" -as [int]) * 1MB
|
41
|
+
$MemoryStartupBytes = ($memory.size."#text" -as [int]) * 1MB
|
42
|
+
$MemoryMinimumBytes = ($memory.reservation."#text" -as [int]) * 1MB
|
43
|
+
|
44
|
+
# Determine boot device
|
45
|
+
Switch ((Select-Xml -xml $vmconfig -XPath "//boot").node.device0."#text") {
|
46
|
+
"Floppy" { $bootdevice = "floppy" }
|
47
|
+
"HardDrive" { $bootdevice = "IDE" }
|
48
|
+
"Optical" { $bootdevice = "CD" }
|
49
|
+
"Network" { $bootdevice = "LegacyNetworkAdapter" }
|
50
|
+
"Default" { $bootdevice = "IDE" }
|
51
|
+
} #switch
|
52
|
+
|
53
|
+
# Define a hash map of parameter values for New-VM
|
54
|
+
|
55
|
+
$vm_params = @{
|
56
|
+
Name = $vm_name
|
57
|
+
NoVHD = $True
|
58
|
+
MemoryStartupBytes = $MemoryStartupBytes
|
59
|
+
BootDevice = $bootdevice
|
60
|
+
ErrorAction = "Stop"
|
61
|
+
}
|
62
|
+
|
63
|
+
# Create the VM using the values in the hash map
|
64
|
+
|
65
|
+
$vm = New-VM @vm_params
|
66
|
+
|
67
|
+
$notes = (Select-Xml -xml $vmconfig -XPath "//notes").node.'#text'
|
68
|
+
|
69
|
+
# Set-VM parameters to configure new VM with old values
|
70
|
+
|
71
|
+
$more_vm_params = @{
|
72
|
+
ProcessorCount = $processors
|
73
|
+
MemoryStartupBytes = $MemoryStartupBytes
|
74
|
+
}
|
75
|
+
|
76
|
+
If ($dynamicmemory) {
|
77
|
+
$more_vm_params.Add("DynamicMemory",$True)
|
78
|
+
$more_vm_params.Add("MemoryMinimumBytes",$MemoryMinimumBytes)
|
79
|
+
$more_vm_params.Add("MemoryMaximumBytes", $MemoryMaximumBytes)
|
80
|
+
} else {
|
81
|
+
$more_vm_params.Add("StaticMemory",$True)
|
82
|
+
}
|
83
|
+
|
84
|
+
if ($notes) {
|
85
|
+
$more_vm_params.Add("Notes",$notes)
|
86
|
+
}
|
87
|
+
|
88
|
+
# Set the values on the VM
|
89
|
+
$vm | Set-VM @more_vm_params -Passthru
|
90
|
+
|
91
|
+
# Add drives to the virtual machine
|
92
|
+
$controllers = Select-Xml -xml $vmconfig -xpath "//*[starts-with(name(.),'controller')]"
|
93
|
+
|
94
|
+
# A regular expression pattern to pull the number from controllers
|
95
|
+
[regex]$rx="\d"
|
96
|
+
|
97
|
+
foreach ($controller in $controllers) {
|
98
|
+
$node = $controller.Node
|
99
|
+
|
100
|
+
# Check for SCSI
|
101
|
+
if ($node.ParentNode.ChannelInstanceGuid) {
|
102
|
+
$ControllerType = "SCSI"
|
103
|
+
} else {
|
104
|
+
$ControllerType = "IDE"
|
105
|
+
}
|
106
|
+
|
107
|
+
$drives = $node.ChildNodes | where {$_.pathname."#text"}
|
108
|
+
foreach ($drive in $drives) {
|
109
|
+
#if drive type is ISO then set DVD Drive accordingly
|
110
|
+
$driveType = $drive.type."#text"
|
111
|
+
|
112
|
+
$addDriveParam = @{
|
113
|
+
ControllerNumber = $rx.Match($controller.node.name).value
|
114
|
+
Path = $vhdx_path
|
115
|
+
}
|
116
|
+
|
117
|
+
if ($drive.pool_id."#text") {
|
118
|
+
$ResourcePoolName = $drive.pool_id."#text"
|
119
|
+
$addDriveParam.Add("ResourcePoolname",$ResourcePoolName)
|
120
|
+
}
|
121
|
+
|
122
|
+
if ($drivetype -eq 'VHD') {
|
123
|
+
$addDriveParam.add("ControllerType",$ControllerType)
|
124
|
+
$vm | Add-VMHardDiskDrive @AddDriveparam
|
125
|
+
}
|
126
|
+
}
|
127
|
+
}
|
128
|
+
|
129
|
+
$vm_id = (Get-VM $vm_name).id.guid
|
130
|
+
$resultHash = @{
|
131
|
+
name = $vm_name
|
132
|
+
id = $vm_id
|
133
|
+
}
|
134
|
+
|
135
|
+
$result = ConvertTo-Json $resultHash
|
136
|
+
Write-Output-Message $result
|