vagrant-windows-hyperv 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|