vagrant-windows-hyperv 1.0.1

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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/Gemfile +15 -0
  4. data/LICENSE.txt +7 -0
  5. data/README.md +89 -0
  6. data/Rakefile +29 -0
  7. data/example_box/metadata.json +1 -0
  8. data/lib/vagrant-windows-hyperv.rb +38 -0
  9. data/lib/vagrant-windows-hyperv/action.rb +81 -0
  10. data/lib/vagrant-windows-hyperv/action/export.rb +54 -0
  11. data/lib/vagrant-windows-hyperv/action/package.rb +21 -0
  12. data/lib/vagrant-windows-hyperv/action/rdp.rb +49 -0
  13. data/lib/vagrant-windows-hyperv/action/setup_package_files.rb +55 -0
  14. data/lib/vagrant-windows-hyperv/command/rdp/command.rb +22 -0
  15. data/lib/vagrant-windows-hyperv/communication/powershell.rb +37 -0
  16. data/lib/vagrant-windows-hyperv/driver.rb +89 -0
  17. data/lib/vagrant-windows-hyperv/errors.rb +31 -0
  18. data/lib/vagrant-windows-hyperv/guest/cap/halt.rb +19 -0
  19. data/lib/vagrant-windows-hyperv/guest/windows.rb +25 -0
  20. data/lib/vagrant-windows-hyperv/monkey_patch/action/provision.rb +32 -0
  21. data/lib/vagrant-windows-hyperv/monkey_patch/machine.rb +22 -0
  22. data/lib/vagrant-windows-hyperv/monkey_patch/plugins/synced_folders/smb/synced_folders.rb +55 -0
  23. data/lib/vagrant-windows-hyperv/monkey_patch/util/powershell.rb +37 -0
  24. data/lib/vagrant-windows-hyperv/plugin.rb +85 -0
  25. data/lib/vagrant-windows-hyperv/provider.rb +30 -0
  26. data/lib/vagrant-windows-hyperv/provisioner/chef_solo.rb +181 -0
  27. data/lib/vagrant-windows-hyperv/provisioner/puppet.rb +99 -0
  28. data/lib/vagrant-windows-hyperv/provisioner/shell.rb +81 -0
  29. data/lib/vagrant-windows-hyperv/scripts/check_winrm.ps1 +41 -0
  30. data/lib/vagrant-windows-hyperv/scripts/export_vm.ps1 +31 -0
  31. data/lib/vagrant-windows-hyperv/scripts/file_sync.ps1 +145 -0
  32. data/lib/vagrant-windows-hyperv/scripts/host_info.ps1 +25 -0
  33. data/lib/vagrant-windows-hyperv/scripts/hyperv_manager.ps1 +36 -0
  34. data/lib/vagrant-windows-hyperv/scripts/run_in_remote.ps1 +31 -0
  35. data/lib/vagrant-windows-hyperv/scripts/upload_file.ps1 +95 -0
  36. data/lib/vagrant-windows-hyperv/scripts/utils/create_session.ps1 +34 -0
  37. data/lib/vagrant-windows-hyperv/scripts/utils/write_messages.ps1 +18 -0
  38. data/lib/vagrant-windows-hyperv/version.rb +10 -0
  39. data/locales/en.yml +15 -0
  40. data/spec/hyper-v/config_spec.rb +36 -0
  41. data/spec/hyper-v/spec_helper.rb +9 -0
  42. data/templates/provisioners/chef-solo/solo.erb +51 -0
  43. data/vagrant-windows-hyperv.gemspec +63 -0
  44. data/vagrantfile_examples/Vagrantfile_linux +23 -0
  45. data/vagrantfile_examples/Vagrantfile_windows +24 -0
  46. metadata +171 -0
@@ -0,0 +1,145 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ param (
7
+ [string]$vm_id = $(throw "-vm_id is required."),
8
+ [string]$guest_ip = $(throw "-guest_ip is required."),
9
+ [string]$username = $(throw "-guest_username is required."),
10
+ [string]$password = $(throw "-guest_password is required."),
11
+ [string]$host_path = $(throw "-host_path is required."),
12
+ [string]$guest_path = $(throw "-guest_path is required.")
13
+ )
14
+
15
+ # Include the following modules
16
+ $presentDir = Split-Path -parent $PSCommandPath
17
+ $modules = @()
18
+ $modules += $presentDir + "\utils\write_messages.ps1"
19
+ $modules += $presentDir + "\utils\create_session.ps1"
20
+ forEach ($module in $modules) { . $module }
21
+
22
+ function Get-file-hash($source_path, $delimiter) {
23
+ $source_files = @()
24
+ (Get-ChildItem $source_path -rec -force | ForEach-Object -Process {
25
+ Get-FileHash -Path $_.FullName -Algorithm MD5 } ) |
26
+ ForEach-Object -Process {
27
+ $source_files += $_.Path.Replace($source_path, "") + $delimiter + $_.Hash
28
+ }
29
+ $source_files
30
+ }
31
+
32
+ function Get-remote-file-hash($source_path, $delimiter, $session) {
33
+ Invoke-Command -Session $session -ScriptBlock ${function:Get-file-hash} -ArgumentList $source_path, $delimiter
34
+ # TODO:
35
+ # Check if remote PS Scripting errors
36
+ }
37
+
38
+ function Sync-Remote-Machine($machine, $remove_files, $copy_files, $host_path, $guest_path) {
39
+ ForEach ($item in $copy_files) {
40
+ $from = $host_path + $item
41
+ $to = $guest_path + $item
42
+ # Copy VM can also take a VM object
43
+ Copy-VMFile -VM $machine -SourcePath $from -DestinationPath $to -CreateFullPath -FileSource Host -Force
44
+ }
45
+ }
46
+
47
+ function Create-Remote-Folders($empty_source_folders, $guest_path) {
48
+
49
+ ForEach ($item in $empty_source_folders) {
50
+ $new_name = $guest_path + $item
51
+ New-Item "$new_name" -type directory -Force
52
+ }
53
+ }
54
+
55
+ function Create-Guest-Folder($guest_path) {
56
+ try {
57
+ if (Test-Path $guest_path) {
58
+ $junction = Get-Item $guest_path
59
+ $junction.Delete()
60
+ }
61
+ }
62
+ # Catch any [IOException]
63
+ catch {
64
+ Remove-Item "$guest_path" -Force -Recurse
65
+ }
66
+ New-Item "$guest_path" -type directory -Force
67
+ }
68
+
69
+ function Get-Empty-folders-From-Source($host_path) {
70
+ Get-ChildItem $host_path -recurse |
71
+ Where-Object {$_.PSIsContainer -eq $True} |
72
+ Where-Object {$_.GetFiles().Count -eq 0} |
73
+ Select-Object FullName | ForEach-Object -Process {
74
+ $empty_source_folders += ($_.FullName.Replace($host_path, ""))
75
+ }
76
+ }
77
+
78
+ $delimiter = " || "
79
+
80
+ $machine = Get-VM -Id $vm_id
81
+
82
+ # FIXME: PowerShell guys please fix this.
83
+ # The below script checks for all VMIntegrationService which are not enabled
84
+ # and will enable this.
85
+ # When when all the services are enabled this throws an error.
86
+ # Enable VMIntegrationService to true
87
+ try {
88
+ Get-VM -Id $vm_id | Get-VMIntegrationService -Name "Guest Service Interface" | Enable-VMIntegrationService -Passthru
89
+ }
90
+ catch { }
91
+
92
+
93
+ $response = Create-Remote-Session $guest_ip $username $password
94
+ if (!$response["session"] -and $response["error"]) {
95
+ $errortHash = @{
96
+ type = "PowerShellError"
97
+ error = $response["error"]
98
+ }
99
+ Write-Error-Message $errortHash
100
+ return
101
+ }
102
+
103
+ $session = $response["session"]
104
+ # Create the guest folder if not exist
105
+ $result = Invoke-Command -Session $session -ScriptBlock ${function:Create-Guest-Folder} -ArgumentList $guest_path
106
+
107
+
108
+ $source_files = Get-file-hash $host_path $delimiter
109
+ $destination_files = Get-remote-file-hash $guest_path $delimiter $session
110
+
111
+ if (!$destination_files) {
112
+ $destination_files = @()
113
+ }
114
+ if (!$source_files) {
115
+ $source_files = @()
116
+ }
117
+
118
+ # Compare source and destination files
119
+ $remove_files = @()
120
+ $copy_files = @()
121
+
122
+
123
+ Compare-Object -ReferenceObject $source_files -DifferenceObject $destination_files | ForEach-Object {
124
+ if ($_.SideIndicator -eq '=>') {
125
+ $remove_files += $_.InputObject.Split($delimiter)[0]
126
+ } else {
127
+ $copy_files += $_.InputObject.Split($delimiter)[0]
128
+ }
129
+ }
130
+
131
+ # Update the files to remote machine
132
+ Sync-Remote-Machine $machine $remove_files $copy_files $host_path $guest_path
133
+
134
+ # Create any empty folders which missed to sync to remote machine
135
+ $empty_source_folders = @()
136
+ $directories = Get-Empty-folders-From-Source $host_path
137
+
138
+ $result = Invoke-Command -Session $session -ScriptBlock ${function:Create-Remote-Folders} -ArgumentList $empty_source_folders, $guest_path
139
+ # Always remove the connection after Use
140
+ Remove-PSSession -Id $session.Id
141
+
142
+ $resultHash = @{
143
+ message = "OK"
144
+ }
145
+ Write-Output-Message $resultHash
@@ -0,0 +1,25 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ # Include the following modules
7
+ $presentDir = Split-Path -parent $PSCommandPath
8
+ . ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
9
+
10
+ try {
11
+ $hostname = $(whoami)
12
+ $ip = (Get-WmiObject -class win32_NetworkAdapterConfiguration -Filter 'ipenabled = "true"').ipaddress[0]
13
+ $resultHash = @{
14
+ host_name = "$username"
15
+ host_ip = "$ip"
16
+ }
17
+ Write-Output-Message $resultHash
18
+ }
19
+ catch {
20
+ $errortHash = @{
21
+ type = "PowerShellError"
22
+ error = "$_"
23
+ }
24
+ Write-Error-Message $errortHash
25
+ }
@@ -0,0 +1,36 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ param (
7
+ [string]$vm_id = $(throw "-vm_id is required."),
8
+ [string]$command = ""
9
+ )
10
+
11
+ # Include the following modules
12
+ $presentDir = Split-Path -parent $PSCommandPath
13
+ . ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
14
+
15
+ try {
16
+ $vm = Get-VM -Id $vm_id -ErrorAction "stop"
17
+ switch ($command) {
18
+ "start" { Start-VM $vm }
19
+ "stop" { Stop-VM $vm }
20
+ "suspend" { Suspend-VM $vm }
21
+ "resume" { Resume-VM $vm }
22
+ }
23
+
24
+ $state = $vm.state
25
+ $status = $vm.status
26
+ $name = $vm.name
27
+ } catch [Microsoft.HyperV.PowerShell.VirtualizationOperationFailedException] {
28
+ $state = "not_created"
29
+ $status = "Not Created"
30
+ }
31
+ $resultHash = @{
32
+ state = "$state"
33
+ status = "$status"
34
+ name = "$name"
35
+ }
36
+ Write-Output-Message $resultHash
@@ -0,0 +1,31 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ param (
7
+ [string]$guest_ip = $(throw "-guest_ip is required."),
8
+ [string]$username = $(throw "-guest_username is required."),
9
+ [string]$password = $(throw "-guest_password is required."),
10
+ [string]$command = ""
11
+ )
12
+
13
+ # Include the following modules
14
+ $presentDir = Split-Path -parent $PSCommandPath
15
+ . ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
16
+ . ([System.IO.Path]::Combine($presentDir, "utils\create_session.ps1"))
17
+
18
+ try {
19
+ $response = Create-Remote-Session $guest_ip $username $password
20
+ if (!$response["session"] -and $response["error"]) {
21
+ Write-Host $response["error"]
22
+ return
23
+ }
24
+ function Remote-Execute($command) {
25
+ cmd /c $command
26
+ }
27
+ Invoke-Command -Session $response["session"] -ScriptBlock ${function:Remote-Execute} -ArgumentList $command -ErrorAction "stop"
28
+ } catch {
29
+ Write-Host $_
30
+ return
31
+ }
@@ -0,0 +1,95 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ param (
7
+ [string]$vm_id = $(throw "-vm_id is required."),
8
+ [string]$host_path = $(throw "-host_path is required."),
9
+ [string]$guest_path = $(throw "-guest_path is required."),
10
+ [string]$guest_ip = $(throw "-guest_ip is required."),
11
+ [string]$username = $(throw "-guest_username is required."),
12
+ [string]$password = $(throw "-guest_password is required.")
13
+ )
14
+
15
+ # Include the following modules
16
+ $presentDir = Split-Path -parent $PSCommandPath
17
+ . ([System.IO.Path]::Combine($presentDir, "utils\write_messages.ps1"))
18
+ . ([System.IO.Path]::Combine($presentDir, "utils\create_session.ps1"))
19
+
20
+ try {
21
+ # Enable Guest Service Interface if they are disabled
22
+ try {
23
+ Get-VM -Id $vm_id | Get-VMIntegrationService -Name "Guest Service Interface" | Enable-VMIntegrationService -Passthru
24
+ }
25
+ catch { }
26
+
27
+ function Upload-FIle-To-VM($host_path, $guest_path, $machine) {
28
+ Write-Host $host_path
29
+ Write-Host $guest_path
30
+ Copy-VMFile -VM $machine -SourcePath $host_path -DestinationPath $guest_path -CreateFullPath -FileSource Host -Force -ErrorAction stop
31
+ }
32
+
33
+ function Prepare-Guest-Folder($guest_ip, $username, $password) {
34
+ $response = Create-Remote-Session $guest_ip $username $password
35
+ if (!$response["session"] -and $response["error"]) {
36
+ $errortHash = @{
37
+ type = "PowerShellError"
38
+ message = $response["error"]
39
+ }
40
+ Write-Error-Message $errorResult
41
+ return
42
+ }
43
+ $session = $response["session"]
44
+ # Create the guest folder if not exist
45
+ $result = Invoke-Command -Session $session -ScriptBlock ${function:Create-Guest-Folder} -ArgumentList $guest_path
46
+ }
47
+
48
+ function Create-Guest-Folder($guest_path) {
49
+ try {
50
+ if (Test-Path $guest_path) {
51
+ # First attempt to remove a Junction drive. The fall back to removing a
52
+ # folder
53
+ $junction = Get-Item $guest_path
54
+ $junction.Delete()
55
+ }
56
+ }
57
+ # Catch any [IOException]
58
+ catch {
59
+ Remove-Item "$guest_path" -Force -Recurse
60
+ }
61
+ New-Item "$guest_path" -type directory -Force
62
+ }
63
+
64
+ $machine = Get-VM -Id $vm_id
65
+ # When Host path is a folder.
66
+ # Find all files within it and copy to the Guest
67
+ if (Test-Path $host_path -pathtype container) {
68
+ # Open a remote PS Session with the guest
69
+ Prepare-Guest-Folder $guest_ip $username $password
70
+ # Copy all files from Host path to Guest Path
71
+ Get-ChildItem $host_path -rec |
72
+ Where-Object {$_.PSIsContainer -eq $false} |
73
+ ForEach-Object -Process {
74
+ $file_name = $_.Fullname.Replace($host_path, "")
75
+ $from = $host_path + $file_name
76
+ $to = $guest_path + $file_name
77
+ # Write-Host $from
78
+ # Write-Host $to
79
+ Upload-FIle-To-VM $from $to $machine
80
+ }
81
+ } elseif (Test-Path $host_path) {
82
+ Upload-FIle-To-VM $host_path $guest_path $machine
83
+ }
84
+ $resultHash = @{
85
+ message = "OK"
86
+ }
87
+ Write-Output-Message $resultHash
88
+ } catch {
89
+ $errortHash = @{
90
+ type = "PowerShellError"
91
+ error ="Failed to copy file $_"
92
+ }
93
+ Write-Error-Message $errortHash
94
+ return
95
+ }
@@ -0,0 +1,34 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ function Get-Remote-Session($guest_ip, $username, $password) {
7
+ $secstr = convertto-securestring -AsPlainText -Force -String $password
8
+ $cred = new-object -typename System.Management.Automation.PSCredential -argumentlist $username, $secstr
9
+ New-PSSession -ComputerName $guest_ip -Credential $cred -ErrorAction "stop"
10
+ }
11
+
12
+ function Create-Remote-Session($guest_ip, $username, $password) {
13
+ $count = 0
14
+ $session_error = ""
15
+ $session = ""
16
+ do {
17
+ $count++
18
+ try {
19
+ $session = Get-Remote-Session $guest_ip $username $password
20
+ $session_error = ""
21
+ }
22
+ catch {
23
+ Start-Sleep -s 1
24
+ $session_error = $_
25
+ $session = ""
26
+ }
27
+ }
28
+ while (!$session -and $count -lt 20)
29
+
30
+ return @{
31
+ session = $session
32
+ error = $session_error
33
+ }
34
+ }
@@ -0,0 +1,18 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ function Write-Error-Message($message) {
7
+ $result = ConvertTo-Json $message
8
+ Write-Host "===Begin-Error==="
9
+ Write-Host $result
10
+ Write-Host "===End-Error==="
11
+ }
12
+
13
+ function Write-Output-Message($message) {
14
+ $result = ConvertTo-Json $message
15
+ Write-Host "===Begin-Output==="
16
+ Write-Host $result
17
+ Write-Host "===End-Output==="
18
+ }
@@ -0,0 +1,10 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ module VagrantPlugins
7
+ module VagrantHyperV
8
+ VERSION = "1.0.1"
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ en:
2
+ vagrant_win_hyperv:
3
+ generating_rdp: |-
4
+ Generating a RDP file to establish a remote session. You will soon be prompted to authenticate the
5
+ RDP session and enter the Virtual Machine's password.
6
+ message_rdp_not_ready: |-
7
+ Hyper-V machine isn't running. Can't RDP in!
8
+ errors:
9
+ ssh_not_available: |-
10
+ SSH is available for non windows guest. Vagrant detected guest to be %{guest}
11
+ rdp_not_available: |-
12
+ RDP is available for windows guest. Vagrant detected guest to be %{guest}
13
+ win_rm_not_ready: |-
14
+ WinRM is not enabled in the remot guest. Vagrant-Windows-HyperV uses remote PowerShell scripts
15
+ to communicate to the remote machine. Please check the same and try again.
@@ -0,0 +1,36 @@
1
+ #-------------------------------------------------------------------------
2
+ # Copyright (c) Microsoft Open Technologies, Inc.
3
+ # All Rights Reserved. Licensed under the Apache 2.0 License.
4
+ #--------------------------------------------------------------------------
5
+
6
+ require "vagrant-windows-hyperv/config"
7
+ require_relative "spec_helper"
8
+
9
+ describe VagrantPlugins::HyperV::Config do
10
+ let(:instance) { VagrantPlugins::HyperV::Config.new }
11
+ let(:machine) { Object.new }
12
+ describe "Check host share config" do
13
+ it "Should return the error messages under a key HyperV" do
14
+ instance.host_config do |share|
15
+ share.username = "vagrant"
16
+ end
17
+ error = instance.validate(machine)
18
+ assert(true, error.has_key?("HyperV"))
19
+ end
20
+ it "Should raise errors for missing properties" do
21
+ instance.host_config do |share|
22
+ share.username = "vagrant"
23
+ end
24
+ error = instance.validate(machine)
25
+ assert(true, !error["HyperV"].empty?)
26
+ end
27
+ it "Should have no errors when all properties are passed" do
28
+ instance.host_config do |share|
29
+ share.username = "vagrant"
30
+ share.password = "my_secret_password"
31
+ end
32
+ error = instance.validate(machine)
33
+ assert(true, error["HyperV"].empty?)
34
+ end
35
+ end
36
+ end