vagrant-windows 1.2.0 → 1.3.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.
- data/.DS_Store +0 -0
- data/CHANGELOG.md +38 -0
- data/Gemfile +2 -1
- data/LICENSE +13 -0
- data/README.md +78 -110
- data/coverage/.last_run.json +1 -1
- data/coverage/.resultset.json +685 -210
- data/coverage/index.html +5333 -2355
- data/init.pp +5 -0
- data/lib/vagrant-windows/communication/winrmcommunicator.rb +49 -61
- data/lib/vagrant-windows/communication/winrmfinder.rb +23 -17
- data/lib/vagrant-windows/communication/winrmshell.rb +34 -16
- data/lib/vagrant-windows/communication/winrmshell_factory.rb +34 -0
- data/lib/vagrant-windows/config/winrm.rb +1 -2
- data/lib/vagrant-windows/errors.rb +2 -2
- data/lib/vagrant-windows/guest/cap/configure_networks.rb +33 -29
- data/lib/vagrant-windows/guest/cap/halt.rb +4 -0
- data/lib/vagrant-windows/guest/cap/mount_shared_folder.rb +31 -0
- data/lib/vagrant-windows/guest/windows.rb +13 -11
- data/lib/vagrant-windows/helper.rb +22 -1
- data/lib/vagrant-windows/monkey_patches/plugins/provisioners/chef/provisioner/chef_solo.rb +17 -5
- data/lib/vagrant-windows/monkey_patches/plugins/provisioners/puppet/provisioner/puppet.rb +54 -17
- data/lib/vagrant-windows/monkey_patches/plugins/provisioners/shell/provisioner.rb +36 -22
- data/lib/vagrant-windows/plugin.rb +4 -4
- data/lib/vagrant-windows/scripts/cheftask.ps1.erb +13 -12
- data/lib/vagrant-windows/scripts/cheftask.xml.erb +1 -1
- data/lib/vagrant-windows/scripts/cheftaskrun.ps1.erb +3 -1
- data/lib/vagrant-windows/scripts/{mount_volume.vmware.ps1.erb → mount_volume.ps1.erb} +2 -1
- data/lib/vagrant-windows/scripts/reboot_detect.ps1 +43 -0
- data/lib/vagrant-windows/version.rb +1 -1
- data/lib/vagrant-windows/windows_machine.rb +87 -0
- data/locales/en.yml +2 -5
- data/puppet-3.3.2.msi +0 -0
- data/spec/vagrant-windows/guestnetwork_spec.rb +14 -2
- data/spec/vagrant-windows/helper_spec.rb +1 -0
- data/spec/vagrant-windows/mount_shared_folder_spec.rb +34 -0
- data/spec/vagrant-windows/windows_config_spec.rb +26 -0
- data/spec/vagrant-windows/windows_machine_spec.rb +65 -0
- data/spec/vagrant-windows/{config_spec.rb → winrm_config_spec.rb} +2 -28
- data/spec/vagrant-windows/winrmcommunicator_spec.rb +29 -8
- data/spec/vagrant-windows/winrmfinder_spec.rb +42 -0
- data/spec/vagrant-windows/winrmshell_spec.rb +39 -0
- data/test.ps1 +1 -0
- data/vagrant-windows.gemspec +6 -5
- metadata +59 -19
- checksums.yaml +0 -7
- data/lib/vagrant-windows/guest/cap/mount_virtualbox_shared_folder.rb +0 -17
- data/lib/vagrant-windows/guest/cap/mount_vmware_shared_folder.rb +0 -15
- data/lib/vagrant-windows/scripts/mount_volume.virtualbox.ps1.erb +0 -49
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'tempfile'
|
|
2
2
|
require "#{Vagrant::source_root}/plugins/provisioners/chef/provisioner/chef_solo"
|
|
3
3
|
require_relative '../../../../../helper'
|
|
4
|
+
require_relative '../../../../../windows_machine'
|
|
4
5
|
|
|
5
6
|
module VagrantPlugins
|
|
6
7
|
module Chef
|
|
@@ -9,11 +10,18 @@ module VagrantPlugins
|
|
|
9
10
|
|
|
10
11
|
include VagrantWindows::Helper
|
|
11
12
|
|
|
13
|
+
provision_on_linux = instance_method(:provision)
|
|
12
14
|
run_chef_solo_on_linux = instance_method(:run_chef_solo)
|
|
13
15
|
|
|
14
16
|
# This patch is needed until Vagrant supports chef on Windows guests
|
|
15
17
|
define_method(:run_chef_solo) do
|
|
16
|
-
is_windows ? run_chef_solo_on_windows() : run_chef_solo_on_linux.bind(self).()
|
|
18
|
+
is_windows? ? run_chef_solo_on_windows() : run_chef_solo_on_linux.bind(self).()
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
define_method(:provision) do
|
|
22
|
+
windows_machine = VagrantWindows::WindowsMachine.new(@machine)
|
|
23
|
+
wait_if_rebooting(windows_machine) if is_windows?
|
|
24
|
+
provision_on_linux.bind(self).()
|
|
17
25
|
end
|
|
18
26
|
|
|
19
27
|
def run_chef_solo_on_windows
|
|
@@ -40,8 +48,12 @@ module VagrantPlugins
|
|
|
40
48
|
else
|
|
41
49
|
@machine.env.ui.info I18n.t("vagrant.provisioners.chef.running_solo_again")
|
|
42
50
|
end
|
|
51
|
+
|
|
52
|
+
# This re-establishes our symbolic links if they were created between now and a reboot
|
|
53
|
+
# Fixes issue #119
|
|
54
|
+
@machine.communicate.execute('& net use a-non-existant-share', :error_check => false)
|
|
43
55
|
|
|
44
|
-
exit_status = @machine.communicate.execute(command) do |type, data|
|
|
56
|
+
exit_status = @machine.communicate.execute(command, :error_check => false) do |type, data|
|
|
45
57
|
# Output the data with the proper color based on the stream.
|
|
46
58
|
color = type == :stdout ? :green : :red
|
|
47
59
|
|
|
@@ -94,10 +106,10 @@ module VagrantPlugins
|
|
|
94
106
|
}
|
|
95
107
|
end
|
|
96
108
|
@chef_script_options
|
|
97
|
-
end
|
|
109
|
+
end
|
|
98
110
|
|
|
99
|
-
def is_windows
|
|
100
|
-
@machine
|
|
111
|
+
def is_windows?
|
|
112
|
+
VagrantWindows::WindowsMachine.is_windows?(@machine)
|
|
101
113
|
end
|
|
102
114
|
|
|
103
115
|
end # ChefSolo class
|
|
@@ -1,24 +1,40 @@
|
|
|
1
1
|
require "#{Vagrant::source_root}/plugins/provisioners/puppet/provisioner/puppet"
|
|
2
|
+
require_relative '../../../../../windows_machine'
|
|
3
|
+
require_relative '../../../../../helper'
|
|
4
|
+
require_relative '../../../../../errors'
|
|
2
5
|
|
|
3
6
|
module VagrantPlugins
|
|
4
7
|
module Puppet
|
|
5
8
|
module Provisioner
|
|
6
9
|
class Puppet < Vagrant.plugin("2", :provisioner)
|
|
7
10
|
|
|
11
|
+
include VagrantWindows::Helper
|
|
12
|
+
|
|
8
13
|
# This patch is needed until Vagrant supports Puppet on Windows guests
|
|
14
|
+
provision_on_linux = instance_method(:provision)
|
|
9
15
|
run_puppet_apply_on_linux = instance_method(:run_puppet_apply)
|
|
10
16
|
configure_on_linux = instance_method(:configure)
|
|
11
|
-
|
|
17
|
+
|
|
12
18
|
define_method(:run_puppet_apply) do
|
|
13
|
-
is_windows ? run_puppet_apply_on_windows() : run_puppet_apply_on_linux.bind(self).()
|
|
19
|
+
is_windows? ? run_puppet_apply_on_windows() : run_puppet_apply_on_linux.bind(self).()
|
|
14
20
|
end
|
|
15
|
-
|
|
21
|
+
|
|
16
22
|
define_method(:configure) do |root_config|
|
|
17
|
-
is_windows ? configure_on_windows(root_config) : configure_on_linux.bind(self).(root_config)
|
|
23
|
+
is_windows? ? configure_on_windows(root_config) : configure_on_linux.bind(self).(root_config)
|
|
18
24
|
end
|
|
19
25
|
|
|
26
|
+
define_method(:provision) do
|
|
27
|
+
windows_machine = VagrantWindows::WindowsMachine.new(@machine)
|
|
28
|
+
wait_if_rebooting(windows_machine) if is_windows?
|
|
29
|
+
provision_on_linux.bind(self).()
|
|
30
|
+
end
|
|
31
|
+
|
|
20
32
|
def run_puppet_apply_on_windows
|
|
21
|
-
|
|
33
|
+
|
|
34
|
+
# This re-establishes our symbolic links if they were created between now and a reboot
|
|
35
|
+
@machine.communicate.execute('& net use a-non-existant-share', :error_check => false)
|
|
36
|
+
|
|
37
|
+
options = [@config.options].flatten
|
|
22
38
|
module_paths = @module_paths.map { |_, to| to }
|
|
23
39
|
if !@module_paths.empty?
|
|
24
40
|
# Prepend the default module path
|
|
@@ -28,49 +44,70 @@ module VagrantPlugins
|
|
|
28
44
|
options << "--modulepath '#{module_paths.join(';')}'"
|
|
29
45
|
end
|
|
30
46
|
|
|
47
|
+
if @hiera_config_path
|
|
48
|
+
options << "--hiera_config=#{@hiera_config_path}"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
if !@machine.env.ui.is_a?(Vagrant::UI::Colored)
|
|
52
|
+
options << "--color=false"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
options << "--manifestdir #{manifests_guest_path}"
|
|
56
|
+
options << "--detailed-exitcodes"
|
|
31
57
|
options << @manifest_file
|
|
32
58
|
options = options.join(" ")
|
|
33
59
|
|
|
34
60
|
# Build up the custom facts if we have any
|
|
35
61
|
facter = ""
|
|
36
|
-
if
|
|
62
|
+
if !@config.facter.empty?
|
|
37
63
|
facts = []
|
|
38
|
-
config.facter.each do |key, value|
|
|
64
|
+
@config.facter.each do |key, value|
|
|
39
65
|
facts << "$env:FACTER_#{key}='#{value}';"
|
|
40
66
|
end
|
|
41
67
|
|
|
42
68
|
facter = "#{facts.join(" ")} "
|
|
43
69
|
end
|
|
44
|
-
|
|
45
|
-
command = "
|
|
46
|
-
|
|
70
|
+
|
|
71
|
+
command = "#{facter} puppet apply #{options}"
|
|
72
|
+
if @config.working_directory
|
|
73
|
+
command = "cd #{@config.working_directory}; if($?) \{ #{command} \}"
|
|
74
|
+
end
|
|
75
|
+
|
|
47
76
|
@machine.env.ui.info I18n.t("vagrant.provisioners.puppet.running_puppet",
|
|
48
77
|
:manifest => @manifest_file)
|
|
49
78
|
|
|
50
|
-
@machine.communicate.sudo(command) do |type, data|
|
|
79
|
+
exit_status = @machine.communicate.sudo(command, :error_check => false) do |type, data|
|
|
51
80
|
if !data.empty?
|
|
52
81
|
@machine.env.ui.info(data, :new_line => false, :prefix => false)
|
|
53
82
|
end
|
|
54
83
|
end
|
|
84
|
+
|
|
85
|
+
# Puppet returns 0 or 2 for success with --detailed-exitcodes
|
|
86
|
+
if ![0,2].include?(exit_status)
|
|
87
|
+
raise ::VagrantWindows::Errors::WinRMExecutionError,
|
|
88
|
+
:shell => :powershell,
|
|
89
|
+
:command => command,
|
|
90
|
+
:message => "Puppet failed with an exit code of #{exit_status}"
|
|
91
|
+
end
|
|
55
92
|
end
|
|
56
|
-
|
|
93
|
+
|
|
57
94
|
def configure_on_windows(root_config)
|
|
58
95
|
# Calculate the paths we're going to use based on the environment
|
|
59
96
|
root_path = @machine.env.root_path
|
|
60
97
|
@expanded_manifests_path = @config.expanded_manifests_path(root_path)
|
|
61
98
|
@expanded_module_paths = @config.expanded_module_paths(root_path)
|
|
62
|
-
@manifest_file = @config.manifest_file
|
|
99
|
+
@manifest_file = File.join(manifests_guest_path, @config.manifest_file)
|
|
63
100
|
|
|
64
101
|
# Setup the module paths
|
|
65
102
|
@module_paths = []
|
|
66
103
|
@expanded_module_paths.each_with_index do |path, i|
|
|
67
|
-
@module_paths << [path, File.join(config.temp_dir, "modules-#{i}")]
|
|
104
|
+
@module_paths << [path, File.join(@config.temp_dir, "modules-#{i}")]
|
|
68
105
|
end
|
|
69
106
|
|
|
70
107
|
@logger.debug("Syncing folders from puppet configure")
|
|
71
108
|
@logger.debug("manifests_guest_path = #{manifests_guest_path}")
|
|
72
109
|
@logger.debug("expanded_manifests_path = #{@expanded_manifests_path}")
|
|
73
|
-
|
|
110
|
+
|
|
74
111
|
# Windows guest volume mounting fails without an "id" specified
|
|
75
112
|
# This hacks around that problem and allows the PS mount script to work
|
|
76
113
|
root_config.vm.synced_folder(
|
|
@@ -91,8 +128,8 @@ module VagrantPlugins
|
|
|
91
128
|
end
|
|
92
129
|
end
|
|
93
130
|
|
|
94
|
-
def is_windows
|
|
95
|
-
@machine
|
|
131
|
+
def is_windows?
|
|
132
|
+
VagrantWindows::WindowsMachine.is_windows?(@machine)
|
|
96
133
|
end
|
|
97
134
|
|
|
98
135
|
end # Puppet class
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require "#{Vagrant::source_root}/plugins/provisioners/shell/provisioner"
|
|
2
2
|
require_relative '../../../../helper'
|
|
3
|
+
require_relative '../../../../windows_machine'
|
|
3
4
|
|
|
4
5
|
module VagrantPlugins
|
|
5
6
|
module Shell
|
|
@@ -11,14 +12,17 @@ module VagrantPlugins
|
|
|
11
12
|
provision_on_linux = instance_method(:provision)
|
|
12
13
|
|
|
13
14
|
define_method(:provision) do
|
|
14
|
-
is_windows ? provision_on_windows() : provision_on_linux.bind(self).()
|
|
15
|
+
VagrantWindows::WindowsMachine.is_windows?(@machine) ? provision_on_windows() : provision_on_linux.bind(self).()
|
|
15
16
|
end
|
|
16
|
-
|
|
17
|
+
|
|
17
18
|
def provision_on_windows
|
|
18
19
|
args = ""
|
|
19
20
|
args = " #{config.args}" if config.args
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
windows_machine = VagrantWindows::WindowsMachine.new(@machine)
|
|
23
|
+
wait_if_rebooting(windows_machine)
|
|
24
|
+
|
|
25
|
+
with_windows_script_file do |path|
|
|
22
26
|
# Upload the script to the machine
|
|
23
27
|
@machine.communicate.tap do |comm|
|
|
24
28
|
# Ensure the uploaded script has a file extension, by default
|
|
@@ -59,29 +63,39 @@ module VagrantPlugins
|
|
|
59
63
|
# This method yields the path to a script to upload and execute
|
|
60
64
|
# on the remote server. This method will properly clean up the
|
|
61
65
|
# script file if needed.
|
|
62
|
-
def
|
|
63
|
-
|
|
66
|
+
def with_windows_script_file
|
|
67
|
+
script = nil
|
|
68
|
+
|
|
69
|
+
if config.remote?
|
|
70
|
+
download_path = @machine.env.tmp_path.join("#{@machine.id}-remote-script")
|
|
71
|
+
download_path.delete if download_path.file?
|
|
72
|
+
|
|
73
|
+
Vagrant::Util::Downloader.new(config.path, download_path).download!
|
|
74
|
+
script = download_path.read
|
|
75
|
+
|
|
76
|
+
download_path.delete
|
|
77
|
+
elsif config.path
|
|
64
78
|
# Just yield the path to that file...
|
|
65
|
-
|
|
79
|
+
root_path = @machine.env.root_path
|
|
80
|
+
script = Pathname.new(config.path).expand_path(root_path).read
|
|
66
81
|
else
|
|
67
|
-
#
|
|
68
|
-
|
|
69
|
-
file = Tempfile.new(['vagrant-powershell', '.ps1'])
|
|
70
|
-
|
|
71
|
-
begin
|
|
72
|
-
file.write(config.inline)
|
|
73
|
-
file.fsync
|
|
74
|
-
file.close
|
|
75
|
-
yield file.path
|
|
76
|
-
ensure
|
|
77
|
-
file.close
|
|
78
|
-
file.unlink
|
|
79
|
-
end
|
|
82
|
+
# The script is just the inline code...
|
|
83
|
+
script = config.inline
|
|
80
84
|
end
|
|
81
|
-
end
|
|
82
85
|
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
# Otherwise we have an inline script, we need to Tempfile it,
|
|
87
|
+
# and handle it specially...
|
|
88
|
+
file = Tempfile.new(['vagrant-powershell', '.ps1'])
|
|
89
|
+
|
|
90
|
+
begin
|
|
91
|
+
file.write(script)
|
|
92
|
+
file.fsync
|
|
93
|
+
file.close
|
|
94
|
+
yield file.path
|
|
95
|
+
ensure
|
|
96
|
+
file.close
|
|
97
|
+
file.unlink
|
|
98
|
+
end
|
|
85
99
|
end
|
|
86
100
|
|
|
87
101
|
end # Provisioner class
|
|
@@ -76,13 +76,13 @@ module VagrantWindows
|
|
|
76
76
|
end
|
|
77
77
|
|
|
78
78
|
guest_capability(:windows, :mount_virtualbox_shared_folder) do
|
|
79
|
-
require_relative "guest/cap/
|
|
80
|
-
VagrantWindows::Guest::Cap::
|
|
79
|
+
require_relative "guest/cap/mount_shared_folder"
|
|
80
|
+
VagrantWindows::Guest::Cap::MountSharedFolder
|
|
81
81
|
end
|
|
82
82
|
|
|
83
83
|
guest_capability(:windows, :mount_vmware_shared_folder) do
|
|
84
|
-
require_relative "guest/cap/
|
|
85
|
-
VagrantWindows::Guest::Cap::
|
|
84
|
+
require_relative "guest/cap/mount_shared_folder"
|
|
85
|
+
VagrantWindows::Guest::Cap::MountSharedFolder
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
end
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
# task already exists, kill it
|
|
4
|
-
schtasks /delete /tn "chef-solo" /f | Out-Null
|
|
5
|
-
}
|
|
1
|
+
# kill the task so we can recreate it
|
|
2
|
+
schtasks /delete /tn "chef-solo" /f 2>&1 | out-null
|
|
6
3
|
|
|
7
4
|
# Ensure the chef task running file doesn't exist from a previous failure
|
|
8
5
|
if (Test-Path "<%= options[:chef_task_running] %>") {
|
|
@@ -34,14 +31,18 @@ $success = $TRUE
|
|
|
34
31
|
while (Test-Path "<%= options[:chef_task_running] %>") {
|
|
35
32
|
Start-Sleep -m 100
|
|
36
33
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
if (Test-Path "<%= options[:chef_stdout_log] %>") {
|
|
35
|
+
$text = (get-content "<%= options[:chef_stdout_log] %>")
|
|
36
|
+
$numLines = ($text | Measure-Object -line).lines
|
|
37
|
+
$numLinesToRead = $numLines - $numLinesRead
|
|
38
|
+
|
|
39
|
+
if ($numLinesToRead -gt 0) {
|
|
40
|
+
$text | select -first $numLinesToRead -skip $numLinesRead | ForEach {
|
|
41
|
+
Write-Host "$_"
|
|
42
|
+
}
|
|
43
|
+
$numLinesRead += $numLinesToRead
|
|
44
|
+
}
|
|
43
45
|
}
|
|
44
|
-
$numLinesRead += $numLinesToRead
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
exit Get-Content "<%= options[:chef_task_exitcode] %>"
|
|
@@ -10,7 +10,9 @@ Try
|
|
|
10
10
|
Finally
|
|
11
11
|
{
|
|
12
12
|
$exitCode | Out-File "<%= options[:chef_task_exitcode] %>"
|
|
13
|
-
|
|
13
|
+
if (Test-Path "<%= options[:chef_task_running] %>") {
|
|
14
|
+
del "<%= options[:chef_task_running] %>"
|
|
15
|
+
}
|
|
14
16
|
}
|
|
15
17
|
|
|
16
18
|
exit $exitCode
|
|
@@ -7,6 +7,7 @@ function Test-ReparsePoint([string]$path) {
|
|
|
7
7
|
|
|
8
8
|
$MountPoint = [System.IO.Path]::GetFullPath("<%= options[:mount_point] %>")
|
|
9
9
|
$ShareName = "<%= options[:share_name] %>"
|
|
10
|
+
$VmProviderUncPath = "<%= options[:vm_provider_unc_path] %>"
|
|
10
11
|
|
|
11
12
|
# https://github.com/BIAINC/vagrant-windows/issues/4
|
|
12
13
|
# Not sure why this works, but it does.
|
|
@@ -41,7 +42,7 @@ if (-not (Test-Path $BaseDirectory))
|
|
|
41
42
|
New-Item $BaseDirectory -Type Directory -Force | Out-Null
|
|
42
43
|
}
|
|
43
44
|
|
|
44
|
-
cmd /c mklink /D "$MountPoint" "
|
|
45
|
+
cmd /c mklink /D "$MountPoint" "$VmProviderUncPath" | out-null
|
|
45
46
|
|
|
46
47
|
if ( $LASTEXITCODE -ne 0 )
|
|
47
48
|
{
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# function to check whether machine is currently shutting down
|
|
2
|
+
function ShuttingDown {
|
|
3
|
+
[string]$sourceCode = @"
|
|
4
|
+
using System;
|
|
5
|
+
using System.Runtime.InteropServices;
|
|
6
|
+
|
|
7
|
+
namespace VagrantWindows {
|
|
8
|
+
public static class RemoteManager {
|
|
9
|
+
private const int SM_SHUTTINGDOWN = 0x2000;
|
|
10
|
+
|
|
11
|
+
[DllImport("User32.dll", CharSet = CharSet.Unicode)]
|
|
12
|
+
private static extern int GetSystemMetrics(int Index);
|
|
13
|
+
|
|
14
|
+
public static bool Shutdown() {
|
|
15
|
+
return (0 != GetSystemMetrics(SM_SHUTTINGDOWN));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
"@
|
|
20
|
+
$type = Add-Type -TypeDefinition $sourceCode -PassThru
|
|
21
|
+
return $type::Shutdown()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (ShuttingDown) {
|
|
25
|
+
exit 1
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
# see if a reboot is scheduled in the future by trying to schedule a reboot
|
|
29
|
+
. shutdown.exe -f -r -t 60
|
|
30
|
+
|
|
31
|
+
if ($LASTEXITCODE -eq 1190) {
|
|
32
|
+
# reboot is already pending
|
|
33
|
+
exit 2
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# Remove the pending reboot we just created above
|
|
37
|
+
if ($LASTEXITCODE -eq 0) {
|
|
38
|
+
. shutdown.exe -a
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
# no reboot in progress or scheduled
|
|
43
|
+
exit 0
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
module VagrantWindows
|
|
2
|
+
|
|
3
|
+
# Provides a wrapper around the Vagrant machine object
|
|
4
|
+
class WindowsMachine
|
|
5
|
+
|
|
6
|
+
attr_reader :machine
|
|
7
|
+
|
|
8
|
+
# Returns true if the specifed Vagrant machine is a Windows guest, otherwise false.
|
|
9
|
+
#
|
|
10
|
+
# @param [Machine] The Vagrant machine object
|
|
11
|
+
# @return [Boolean]
|
|
12
|
+
def self.is_windows?(machine)
|
|
13
|
+
machine.config.vm.guest.eql? :windows
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @param [Machine] The Vagrant machine object
|
|
17
|
+
def initialize(machine)
|
|
18
|
+
@machine = machine
|
|
19
|
+
@logger = Log4r::Logger.new("vagrant_windows::windows_machine")
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Checks to see if the machine is using VMWare Fusion or Workstation.
|
|
23
|
+
#
|
|
24
|
+
# @return [Boolean]
|
|
25
|
+
def is_vmware?()
|
|
26
|
+
@machine.provider_name.to_s().start_with?('vmware')
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Checks to see if the machine is using Oracle VirtualBox.
|
|
30
|
+
#
|
|
31
|
+
# @return [Boolean]
|
|
32
|
+
def is_virtualbox?()
|
|
33
|
+
@machine.provider_name.to_s().start_with?('virtualbox')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Checks to see if the machine is rebooting or has a scheduled reboot.
|
|
37
|
+
#
|
|
38
|
+
# @return [Boolean] True if rebooting
|
|
39
|
+
def is_rebooting?()
|
|
40
|
+
reboot_detect_script = VagrantWindows.load_script('reboot_detect.ps1')
|
|
41
|
+
@machine.communicate.execute(reboot_detect_script, :error_check => false) != 0
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Returns the active WinRMShell for the guest.
|
|
45
|
+
#
|
|
46
|
+
# @return [WinRMShell]
|
|
47
|
+
def winrmshell()
|
|
48
|
+
@machine.communicate.winrmshell
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Reads the machine's MAC addresses keyed by interface index.
|
|
52
|
+
# {1=>"0800273FAC5A", 2=>"08002757E68A"}
|
|
53
|
+
#
|
|
54
|
+
# @return [Hash]
|
|
55
|
+
def read_mac_addresses()
|
|
56
|
+
@machine.provider.driver.read_mac_addresses
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Returns a list of forwarded ports for a VM.
|
|
60
|
+
# NOTE: Only the VBox provider currently supports this method
|
|
61
|
+
#
|
|
62
|
+
# @return [Array<Array>]
|
|
63
|
+
def read_forwarded_ports()
|
|
64
|
+
if is_virtualbox?()
|
|
65
|
+
@machine.provider.driver.read_forwarded_ports
|
|
66
|
+
else
|
|
67
|
+
[]
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Returns the SSH config for this machine.
|
|
72
|
+
#
|
|
73
|
+
# @return [Hash]
|
|
74
|
+
def ssh_info()
|
|
75
|
+
@machine.ssh_info
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def windows_config()
|
|
79
|
+
@machine.config.windows
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def winrm_config()
|
|
83
|
+
@machine.config.winrm
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
end
|
data/locales/en.yml
CHANGED
|
@@ -2,11 +2,8 @@ en:
|
|
|
2
2
|
vagrant_windows:
|
|
3
3
|
|
|
4
4
|
errors:
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Host port: %{port}
|
|
9
|
-
Guest port: %{guest_port}
|
|
5
|
+
winrm_not_ready: |-
|
|
6
|
+
The box is not ready for WinRM connections yet.
|
|
10
7
|
winrm_invalid_shell: |-
|
|
11
8
|
%{shell} is not a supported type of Windows shell.
|
|
12
9
|
winrm_execution_error: |-
|
data/puppet-3.3.2.msi
ADDED
|
Binary file
|
|
@@ -5,7 +5,7 @@ describe VagrantWindows::Communication::GuestNetwork , :integration => true do
|
|
|
5
5
|
before(:all) do
|
|
6
6
|
# This test requires you already have a running Windows Server 2008 R2 Vagrant VM
|
|
7
7
|
# Not ideal, but you have to start somewhere
|
|
8
|
-
@shell = VagrantWindows::Communication::WinRMShell.new("
|
|
8
|
+
@shell = VagrantWindows::Communication::WinRMShell.new("127.0.0.1", "vagrant", "vagrant")
|
|
9
9
|
@guestnetwork = VagrantWindows::Communication::GuestNetwork.new(@shell)
|
|
10
10
|
end
|
|
11
11
|
|
|
@@ -35,8 +35,20 @@ describe VagrantWindows::Communication::GuestNetwork , :integration => true do
|
|
|
35
35
|
|
|
36
36
|
it "should configure static IP for adapter" do
|
|
37
37
|
nics = @guestnetwork.network_adapters()
|
|
38
|
-
@guestnetwork.configure_static_interface(
|
|
38
|
+
@guestnetwork.configure_static_interface(
|
|
39
|
+
nics[1][:index],
|
|
40
|
+
nics[1][:net_connection_id],
|
|
41
|
+
"192.168.0.121",
|
|
42
|
+
"255.255.255.0")
|
|
43
|
+
|
|
39
44
|
expect(@guestnetwork.is_dhcp_enabled(nics[1][:index])).to be_false
|
|
45
|
+
|
|
46
|
+
# ensure the right IP was set by looking through all the output of ipconfig
|
|
47
|
+
ipconfig_out = ''
|
|
48
|
+
@shell.powershell('ipconfig /all') do |_, line|
|
|
49
|
+
ipconfig_out = ipconfig_out + "#{line}"
|
|
50
|
+
end
|
|
51
|
+
expect(ipconfig_out).to include('192.168.0.121')
|
|
40
52
|
end
|
|
41
53
|
|
|
42
54
|
it "should configure all networks to work mode" do
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'mocha/api'
|
|
3
|
+
require 'vagrant-windows/guest/cap/mount_shared_folder'
|
|
4
|
+
|
|
5
|
+
describe VagrantWindows::Guest::Cap::MountSharedFolder, :unit => true do
|
|
6
|
+
|
|
7
|
+
before(:each) do
|
|
8
|
+
@communicator = mock()
|
|
9
|
+
@machine = stub(:communicate => @communicator)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
describe "mount_virtualbox_shared_folder" do
|
|
13
|
+
it "should run script with vbox paths" do
|
|
14
|
+
@communicator.expects(:execute).with do |script, options|
|
|
15
|
+
expect(script).to include("$VmProviderUncPath = \"\\\\vboxsrv\\vagrant\"")
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
VagrantWindows::Guest::Cap::MountSharedFolder.mount_virtualbox_shared_folder(
|
|
19
|
+
@machine, "vagrant", "/tmp/vagrant", {})
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "mount_vmware_shared_folder" do
|
|
24
|
+
it "should run script with vmware paths" do
|
|
25
|
+
@communicator.expects(:execute).with do |script, options|
|
|
26
|
+
expect(script).to include("$VmProviderUncPath = \"\\\\vmware-host\\Shared Folders\\vagrant\"")
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
VagrantWindows::Guest::Cap::MountSharedFolder.mount_vmware_shared_folder(
|
|
30
|
+
@machine, "vagrant", "/tmp/vagrant", {})
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe VagrantWindows::Config::Windows , :unit => true do
|
|
4
|
+
let(:instance) { described_class.new }
|
|
5
|
+
|
|
6
|
+
describe "defaults" do
|
|
7
|
+
subject do
|
|
8
|
+
instance.tap do |o|
|
|
9
|
+
o.finalize!
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
its("halt_timeout") { should == 30 }
|
|
14
|
+
its("halt_check_interval") { should == 1 }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "overriding defaults" do
|
|
18
|
+
[:halt_timeout, :halt_check_interval].each do |attribute|
|
|
19
|
+
it "should not default #{attribute} if overridden" do
|
|
20
|
+
instance.send("#{attribute}=".to_sym, 10)
|
|
21
|
+
instance.finalize!
|
|
22
|
+
instance.send(attribute).should == 10
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|