vagrant-windows 0.1.2 → 1.0.0
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 +7 -0
- data/Gemfile.lock +6 -26
- data/README.md +92 -44
- data/lib/vagrant-windows/communication/winrmcommunicator.rb +213 -0
- data/lib/vagrant-windows/config/windows.rb +20 -16
- data/lib/vagrant-windows/config/winrm.rb +35 -15
- data/lib/vagrant-windows/errors.rb +17 -12
- data/lib/vagrant-windows/guest/windows.rb +45 -40
- data/lib/vagrant-windows/monkey_patches/chef_solo.rb +61 -0
- data/lib/vagrant-windows/monkey_patches/machine.rb +25 -0
- data/lib/vagrant-windows/monkey_patches/puppet.rb +100 -0
- data/lib/vagrant-windows/plugin.rb +96 -0
- data/lib/vagrant-windows/scripts/command_alias.ps1 +13 -4
- data/lib/vagrant-windows/scripts/ps_runas.ps1.erb +56 -0
- data/lib/vagrant-windows/version.rb +1 -1
- data/lib/vagrant-windows.rb +33 -0
- data/locales/en.yml +29 -0
- data/vagrant-windows.gemspec +0 -1
- metadata +17 -36
- data/lib/vagrant-windows/communication/winrm.rb +0 -185
- data/lib/vagrant-windows/monkey_patches/driver.rb +0 -57
- data/lib/vagrant-windows/monkey_patches/vm.rb +0 -16
- data/lib/vagrant-windows/winrm.rb +0 -82
- data/lib/vagrant_init.rb +0 -21
@@ -1,45 +1,52 @@
|
|
1
|
-
module
|
1
|
+
module VagrantWindows
|
2
2
|
module Guest
|
3
3
|
# A general Vagrant system implementation for "windows".
|
4
4
|
#
|
5
5
|
# Contributed by Chris McClimans <chris@hippiehacker.org>
|
6
|
-
class Windows <
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
class Windows < Vagrant.plugin("2", :guest)
|
7
|
+
|
8
|
+
attr_reader :machine
|
9
|
+
|
10
|
+
def initialize(machine)
|
11
|
+
super(machine)
|
12
|
+
@machine = machine
|
13
|
+
@logger = Log4r::Logger.new("vagrant_windows::guest::windows")
|
11
14
|
end
|
12
15
|
|
13
16
|
def change_host_name(name)
|
17
|
+
@logger.info("change host name to: #{name}")
|
14
18
|
#### on windows, renaming a computer seems to require a reboot
|
15
|
-
|
19
|
+
@machine.communicate.execute(
|
20
|
+
"wmic computersystem where name=\"%COMPUTERNAME%\" call rename name=\"#{name}\"",
|
21
|
+
:shell => :cmd)
|
16
22
|
end
|
17
23
|
|
18
24
|
# TODO: I am sure that ciphering windows versions will be important at some point
|
19
25
|
def distro_dispatch
|
26
|
+
@logger.info("distro_dispatch: windows")
|
20
27
|
:windows
|
21
28
|
end
|
22
29
|
|
23
30
|
def halt
|
24
|
-
@
|
31
|
+
@machine.communicate.execute("shutdown /s /t 1 /c \"Vagrant Halt\" /f /d p:4:1")
|
25
32
|
|
26
33
|
# Wait until the VM's state is actually powered off. If this doesn't
|
27
34
|
# occur within a reasonable amount of time (15 seconds by default),
|
28
35
|
# then simply return and allow Vagrant to kill the machine.
|
29
36
|
count = 0
|
30
|
-
while @
|
37
|
+
while @machine.state != :poweroff
|
31
38
|
count += 1
|
32
39
|
|
33
|
-
return if count >= @
|
34
|
-
sleep @
|
40
|
+
return if count >= @machine.config.windows.halt_timeout
|
41
|
+
sleep @machine.config.windows.halt_check_interval
|
35
42
|
end
|
36
43
|
end
|
37
44
|
|
38
45
|
def mount_shared_folder(name, guestpath, options)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
@
|
46
|
+
@logger.info("mount_shared_folder: #{name}")
|
47
|
+
mount_script = VagrantWindows.load_script_template("mount_volume.ps1",
|
48
|
+
:options => {:mount_point => guestpath, :name => name})
|
49
|
+
@machine.communicate.execute(mount_script, {:shell => :powershell})
|
43
50
|
end
|
44
51
|
|
45
52
|
def mount_nfs(ip, folders)
|
@@ -51,54 +58,52 @@ module Vagrant
|
|
51
58
|
# real_guestpath = expanded_guest_path(opts[:guestpath])
|
52
59
|
|
53
60
|
# Do the actual creating and mounting
|
54
|
-
# @
|
55
|
-
# @
|
61
|
+
# @machine.communicate.sudo("mkdir -p #{real_guestpath}")
|
62
|
+
# @machine.communicate.sudo("mount -o vers=#{opts[:nfs_version]} #{ip}:'#{opts[:hostpath]}' #{real_guestpath}",
|
56
63
|
# :error_class => LinuxError,
|
57
64
|
# :error_key => :mount_nfs_fail)
|
58
65
|
#end
|
59
66
|
end
|
60
67
|
|
61
68
|
def configure_networks(networks)
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
69
|
+
@logger.info("configure_networks: #{networks.inspect}")
|
70
|
+
|
71
|
+
# The VBox driver 4.0 and 4.1 implement read_mac_addresses, but 4.2 does not?
|
72
|
+
begin
|
73
|
+
driver_mac_address = @machine.provider.driver.read_mac_addresses.invert
|
74
|
+
rescue NoMethodError
|
75
|
+
driver_mac_address = {}
|
76
|
+
driver_mac_address[@machine.provider.driver.read_mac_address] = "macaddress1"
|
66
77
|
end
|
67
78
|
|
68
79
|
vm_interface_map = {}
|
69
|
-
|
80
|
+
|
81
|
+
# NetConnectionStatus=2 -- connected
|
82
|
+
wql = "SELECT * FROM Win32_NetworkAdapter WHERE NetConnectionStatus=2"
|
83
|
+
@machine.communicate.session.wql(wql)[:win32_network_adapter].each do |nic|
|
70
84
|
naked_mac = nic[:mac_address].gsub(':','')
|
71
85
|
if driver_mac_address[naked_mac]
|
72
|
-
vm_interface_map[driver_mac_address[naked_mac]] =
|
86
|
+
vm_interface_map[driver_mac_address[naked_mac]] =
|
87
|
+
{ :name => nic[:net_connection_id], :mac_address => naked_mac, :index => nic[:interface_index] }
|
73
88
|
end
|
74
89
|
end
|
90
|
+
|
75
91
|
networks.each do |network|
|
92
|
+
netsh = "netsh interface ip set address \"#{vm_interface_map[network[:interface]+1][:name]}\" "
|
76
93
|
if network[:type].to_sym == :static
|
77
|
-
|
94
|
+
netsh = "#{netsh} static #{network[:ip]} #{network[:netmask]}"
|
78
95
|
elsif network[:type].to_sym == :dhcp
|
79
|
-
|
96
|
+
netsh = "#{netsh} dhcp"
|
97
|
+
else
|
98
|
+
raise WindowsError, "#{network[:type]} network type is not supported, try static or dhcp"
|
80
99
|
end
|
100
|
+
@machine.communicate.execute(netsh)
|
81
101
|
end
|
82
102
|
|
83
103
|
#netsh interface ip set address name="Local Area Connection" static 192.168.0.100 255.255.255.0 192.168.0.1 1
|
84
104
|
|
85
105
|
end
|
86
106
|
|
87
|
-
|
88
|
-
def windows_path(path)
|
89
|
-
p = ''
|
90
|
-
if path =~ /^\//
|
91
|
-
p << 'C:\\'
|
92
|
-
end
|
93
|
-
p << path
|
94
|
-
p.gsub! /\//, "\\"
|
95
|
-
p.gsub /\\\\{0,}/, "\\"
|
96
|
-
end
|
97
|
-
|
98
|
-
|
99
|
-
|
100
107
|
end
|
101
108
|
end
|
102
109
|
end
|
103
|
-
|
104
|
-
Vagrant.guests.register(:windows) { Vagrant::Guest::Windows }
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "#{VagrantWindows::vagrant_root}/plugins/provisioners/chef/provisioner/chef_solo"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Chef
|
5
|
+
module Provisioner
|
6
|
+
class ChefSolo < Base
|
7
|
+
|
8
|
+
run_chef_solo_on_linux = instance_method(:run_chef_solo)
|
9
|
+
|
10
|
+
# This patch is needed until Vagrant supports chef on Windows guests
|
11
|
+
define_method(:run_chef_solo) do
|
12
|
+
is_windows ? run_chef_solo_on_windows() : run_chef_solo_on_linux.bind(self).()
|
13
|
+
end
|
14
|
+
|
15
|
+
def run_chef_solo_on_windows
|
16
|
+
command_env = @config.binary_env ? "#{@config.binary_env} " : ""
|
17
|
+
command_args = @config.arguments ? " #{@config.arguments}" : ""
|
18
|
+
command_solo = "#{command_env}#{chef_binary_path("chef-solo")} "
|
19
|
+
command_solo << "-c #{@config.provisioning_path}/solo.rb "
|
20
|
+
command_solo << "-j #{@config.provisioning_path}/dna.json "
|
21
|
+
command_solo << "#{command_args}"
|
22
|
+
|
23
|
+
command = VagrantWindows.load_script_template("ps_runas.ps1",
|
24
|
+
:options => {
|
25
|
+
:user => machine.config.winrm.username,
|
26
|
+
:password => @machine.config.winrm.password,
|
27
|
+
:cmd => "powershell.exe",
|
28
|
+
:arguments => "-Command #{command_solo}"})
|
29
|
+
|
30
|
+
@config.attempts.times do |attempt|
|
31
|
+
if attempt == 0
|
32
|
+
@machine.env.ui.info I18n.t("vagrant.provisioners.chef.running_solo")
|
33
|
+
else
|
34
|
+
@machine.env.ui.info I18n.t("vagrant.provisioners.chef.running_solo_again")
|
35
|
+
end
|
36
|
+
|
37
|
+
exit_status = @machine.communicate.sudo(command, :error_check => false) do |type, data|
|
38
|
+
# Output the data with the proper color based on the stream.
|
39
|
+
color = type == :stdout ? :green : :red
|
40
|
+
|
41
|
+
# Note: Be sure to chomp the data to avoid the newlines that the
|
42
|
+
# Chef outputs.
|
43
|
+
@machine.env.ui.info(data.chomp, :color => color, :prefix => false)
|
44
|
+
end
|
45
|
+
|
46
|
+
# There is no need to run Chef again if it converges
|
47
|
+
return if exit_status == 0
|
48
|
+
end
|
49
|
+
|
50
|
+
# If we reached this point then Chef never converged! Error.
|
51
|
+
raise ChefError, :no_convergence
|
52
|
+
end
|
53
|
+
|
54
|
+
def is_windows
|
55
|
+
@machine.config.vm.guest.eql? :windows
|
56
|
+
end
|
57
|
+
|
58
|
+
end # ChefSolo class
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Vagrant
|
2
|
+
class Machine
|
3
|
+
|
4
|
+
ssh_communicate = instance_method(:communicate)
|
5
|
+
|
6
|
+
# This patch is needed until Vagrant supports a configurable communication channel
|
7
|
+
define_method(:communicate) do
|
8
|
+
unless @communicator
|
9
|
+
if @config.vm.guest.eql? :windows
|
10
|
+
@logger.info("guest is #{@config.vm.guest}, using WinRM for communication channel")
|
11
|
+
@communicator = ::VagrantWindows::Communication::WinRMCommunicator.new(self)
|
12
|
+
else
|
13
|
+
@logger.info("guest is #{@config.vm.guest}, using SSH for communication channel")
|
14
|
+
@communicator = ssh_communicate.bind(self).()
|
15
|
+
end
|
16
|
+
end
|
17
|
+
@communicator
|
18
|
+
end
|
19
|
+
|
20
|
+
def winrm
|
21
|
+
@winrm ||= WinRM.new(self)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require "#{VagrantWindows::vagrant_root}/plugins/provisioners/puppet/provisioner/puppet"
|
2
|
+
|
3
|
+
module VagrantPlugins
|
4
|
+
module Puppet
|
5
|
+
module Provisioner
|
6
|
+
class Puppet < Vagrant.plugin("2", :provisioner)
|
7
|
+
|
8
|
+
# This patch is needed until Vagrant supports Puppet on Windows guests
|
9
|
+
run_puppet_apply_on_linux = instance_method(:run_puppet_apply)
|
10
|
+
configure_on_linux = instance_method(:configure)
|
11
|
+
|
12
|
+
define_method(:run_puppet_apply) do
|
13
|
+
is_windows ? run_puppet_apply_on_windows() : run_puppet_apply_on_linux.bind(self).()
|
14
|
+
end
|
15
|
+
|
16
|
+
define_method(:configure) do |root_config|
|
17
|
+
is_windows ? configure_on_windows(root_config) : configure_on_linux.bind(self).(root_config)
|
18
|
+
end
|
19
|
+
|
20
|
+
def run_puppet_apply_on_windows
|
21
|
+
options = [config.options].flatten
|
22
|
+
module_paths = @module_paths.map { |_, to| to }
|
23
|
+
if !@module_paths.empty?
|
24
|
+
# Prepend the default module path
|
25
|
+
module_paths.unshift("/etc/puppet/modules")
|
26
|
+
|
27
|
+
# Add the command line switch to add the module path
|
28
|
+
options << "--modulepath '#{module_paths.join(';')}'"
|
29
|
+
end
|
30
|
+
|
31
|
+
options << @manifest_file
|
32
|
+
options = options.join(" ")
|
33
|
+
|
34
|
+
# Build up the custom facts if we have any
|
35
|
+
facter = ""
|
36
|
+
if !config.facter.empty?
|
37
|
+
facts = []
|
38
|
+
config.facter.each do |key, value|
|
39
|
+
facts << "$env:FACTER_#{key}='#{value}';"
|
40
|
+
end
|
41
|
+
|
42
|
+
facter = "#{facts.join(" ")} "
|
43
|
+
end
|
44
|
+
|
45
|
+
command = "cd #{manifests_guest_path}; if($?) \{ #{facter} puppet apply #{options} \}"
|
46
|
+
|
47
|
+
@machine.env.ui.info I18n.t("vagrant.provisioners.puppet.running_puppet",
|
48
|
+
:manifest => @manifest_file)
|
49
|
+
|
50
|
+
@machine.communicate.sudo(command) do |type, data|
|
51
|
+
data.chomp!
|
52
|
+
@machine.env.ui.info(data, :prefix => false) if !data.empty?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def configure_on_windows(root_config)
|
57
|
+
# Calculate the paths we're going to use based on the environment
|
58
|
+
root_path = @machine.env.root_path
|
59
|
+
@expanded_manifests_path = @config.expanded_manifests_path(root_path)
|
60
|
+
@expanded_module_paths = @config.expanded_module_paths(root_path)
|
61
|
+
@manifest_file = @config.manifest_file
|
62
|
+
|
63
|
+
# Setup the module paths
|
64
|
+
@module_paths = []
|
65
|
+
@expanded_module_paths.each_with_index do |path, i|
|
66
|
+
@module_paths << [path, File.join(config.pp_path, "modules-#{i}")]
|
67
|
+
end
|
68
|
+
|
69
|
+
@logger.debug("Syncing folders from puppet configure")
|
70
|
+
@logger.debug("manifests_guest_path = #{manifests_guest_path}")
|
71
|
+
@logger.debug("expanded_manifests_path = #{@expanded_manifests_path}")
|
72
|
+
|
73
|
+
# Windows guest volume mounting fails without an "id" specified
|
74
|
+
# This hacks around that problem and allows the PS mount script to work
|
75
|
+
root_config.vm.synced_folder(
|
76
|
+
@expanded_manifests_path, manifests_guest_path,
|
77
|
+
:id => "v-manifests-1")
|
78
|
+
|
79
|
+
# Share the manifests directory with the guest
|
80
|
+
#root_config.vm.synced_folder(
|
81
|
+
# @expanded_manifests_path, manifests_guest_path)
|
82
|
+
|
83
|
+
# Share the module paths
|
84
|
+
count = 0
|
85
|
+
@module_paths.each do |from, to|
|
86
|
+
# Sorry for the cryptic key here, but VirtualBox has a strange limit on
|
87
|
+
# maximum size for it and its something small (around 10)
|
88
|
+
root_config.vm.synced_folder(from, to)
|
89
|
+
count += 1
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def is_windows
|
94
|
+
@machine.config.vm.guest.eql? :windows
|
95
|
+
end
|
96
|
+
|
97
|
+
end # Puppet class
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
begin
|
2
|
+
require "vagrant"
|
3
|
+
rescue LoadError
|
4
|
+
raise "The Vagrant Windows plugin must be run within Vagrant."
|
5
|
+
end
|
6
|
+
|
7
|
+
# This is a sanity check to make sure no one is attempting to install
|
8
|
+
# this into an early Vagrant version.
|
9
|
+
if Vagrant::VERSION < "1.1.0"
|
10
|
+
raise "The Vagrant Windows plugin is only compatible with Vagrant 1.1+"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Add vagrant-windows plugin errors
|
14
|
+
require "vagrant-windows/errors"
|
15
|
+
|
16
|
+
# Add Vagrant WinRM communication channel
|
17
|
+
require "vagrant-windows/communication/winrmcommunicator"
|
18
|
+
|
19
|
+
# Monkey Patch the VM object to support multiple channels, i.e. WinRM
|
20
|
+
require "vagrant-windows/monkey_patches/machine"
|
21
|
+
|
22
|
+
# Monkey patch the Puppet provisioner to support PowerShell/Windows
|
23
|
+
require "vagrant-windows/monkey_patches/puppet"
|
24
|
+
|
25
|
+
# Monkey patch the Chef-Solo provisioner to support PowerShell/Windows
|
26
|
+
require "vagrant-windows/monkey_patches/chef_solo"
|
27
|
+
|
28
|
+
# Add our windows specific config object
|
29
|
+
require "vagrant-windows/config/windows"
|
30
|
+
|
31
|
+
# Add our winrm specific config object
|
32
|
+
require "vagrant-windows/config/winrm"
|
33
|
+
|
34
|
+
# Add the new Vagrant Windows guest
|
35
|
+
require "vagrant-windows/guest/windows"
|
36
|
+
|
37
|
+
module VagrantWindows
|
38
|
+
class Plugin < Vagrant.plugin("2")
|
39
|
+
name "Windows guest"
|
40
|
+
description <<-DESC
|
41
|
+
This plugin installs a provider that allows Vagrant to manage
|
42
|
+
Windows machines as guests.
|
43
|
+
DESC
|
44
|
+
|
45
|
+
guest(:windows) do
|
46
|
+
VagrantWindows::Guest::Windows
|
47
|
+
end
|
48
|
+
|
49
|
+
config(:windows) do
|
50
|
+
VagrantWindows::Config::Windows
|
51
|
+
end
|
52
|
+
|
53
|
+
config(:winrm) do
|
54
|
+
VagrantWindows::Config::WinRM
|
55
|
+
end
|
56
|
+
|
57
|
+
# This initializes the internationalization strings.
|
58
|
+
def self.setup_i18n
|
59
|
+
I18n.load_path << File.expand_path("locales/en.yml", VagrantWindows.vagrant_windows_root)
|
60
|
+
I18n.reload!
|
61
|
+
end
|
62
|
+
|
63
|
+
# This sets up our log level to be whatever VAGRANT_LOG is.
|
64
|
+
def self.setup_logging
|
65
|
+
require "log4r"
|
66
|
+
|
67
|
+
level = nil
|
68
|
+
begin
|
69
|
+
level = Log4r.const_get(ENV["VAGRANT_LOG"].upcase)
|
70
|
+
rescue NameError
|
71
|
+
# This means that the logging constant wasn't found,
|
72
|
+
# which is fine. We just keep `level` as `nil`. But
|
73
|
+
# we tell the user.
|
74
|
+
level = nil
|
75
|
+
end
|
76
|
+
|
77
|
+
# Some constants, such as "true" resolve to booleans, so the
|
78
|
+
# above error checking doesn't catch it. This will check to make
|
79
|
+
# sure that the log level is an integer, as Log4r requires.
|
80
|
+
level = nil if !level.is_a?(Integer)
|
81
|
+
|
82
|
+
# Set the logging level on all "vagrant" namespaced
|
83
|
+
# logs as long as we have a valid level.
|
84
|
+
if level
|
85
|
+
logger = Log4r::Logger.new("vagrant_windows")
|
86
|
+
logger.outputters = Log4r::Outputter.stderr
|
87
|
+
logger.level = level
|
88
|
+
logger = nil
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
VagrantWindows::Plugin.setup_logging()
|
96
|
+
VagrantWindows::Plugin.setup_i18n()
|
@@ -1,10 +1,19 @@
|
|
1
1
|
function which {
|
2
|
-
$command = [Array](Get-Command $args[0] -errorAction
|
3
|
-
|
2
|
+
$command = [Array](Get-Command $args[0] -errorAction SilentlyContinue)
|
3
|
+
if($null -eq $command)
|
4
|
+
{
|
5
|
+
exit 1
|
6
|
+
}
|
7
|
+
write-host $command[0].Definition
|
8
|
+
exit 0
|
4
9
|
}
|
5
10
|
|
6
11
|
function test ([Switch] $d, [String] $path) {
|
7
|
-
|
12
|
+
if(Test-Path $path)
|
13
|
+
{
|
14
|
+
exit 0
|
15
|
+
}
|
16
|
+
exit 1
|
8
17
|
}
|
9
18
|
|
10
19
|
function chown {
|
@@ -17,7 +26,7 @@ function mkdir ([Switch] $p, [String] $path)
|
|
17
26
|
{
|
18
27
|
exit 0
|
19
28
|
} else {
|
20
|
-
New-Item $
|
29
|
+
New-Item $path -Type Directory -Force | Out-Null
|
21
30
|
}
|
22
31
|
}
|
23
32
|
|
@@ -0,0 +1,56 @@
|
|
1
|
+
function ps-runas ([String] $user, [String] $password, [String] $cmd, [String] $arguments)
|
2
|
+
{
|
3
|
+
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
|
4
|
+
$process = New-Object System.Diagnostics.Process
|
5
|
+
$setup = $process.StartInfo
|
6
|
+
$setup.FileName = $cmd
|
7
|
+
$setup.Arguments = $arguments
|
8
|
+
$setup.UserName = $user
|
9
|
+
$setup.Password = $secpasswd
|
10
|
+
$setup.Verb = "runas"
|
11
|
+
$setup.UseShellExecute = $false
|
12
|
+
$setup.RedirectStandardError = $true
|
13
|
+
$setup.RedirectStandardOutput = $true
|
14
|
+
$setup.RedirectStandardInput = $false
|
15
|
+
|
16
|
+
$errEvent = Register-ObjectEvent -InputObj $process `
|
17
|
+
-Event "ErrorDataReceived" `
|
18
|
+
-Action `
|
19
|
+
{
|
20
|
+
param([System.Object] $sender, [System.Diagnostics.DataReceivedEventArgs] $e)
|
21
|
+
if ($e.Data)
|
22
|
+
{
|
23
|
+
Write-Host $e.Data
|
24
|
+
}
|
25
|
+
else
|
26
|
+
{
|
27
|
+
New-Event -SourceIdentifier "LastMsgReceived"
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
$outEvent = Register-ObjectEvent -InputObj $process `
|
32
|
+
-Event "OutputDataReceived" `
|
33
|
+
-Action `
|
34
|
+
{
|
35
|
+
param([System.Object] $sender, [System.Diagnostics.DataReceivedEventArgs] $e)
|
36
|
+
Write-Host $e.Data
|
37
|
+
}
|
38
|
+
|
39
|
+
$exitCode = -1
|
40
|
+
if ($process.Start())
|
41
|
+
{
|
42
|
+
$process.BeginOutputReadLine()
|
43
|
+
$process.BeginErrorReadLine()
|
44
|
+
|
45
|
+
$process.WaitForExit()
|
46
|
+
$exitCode = [int]$process.ExitCode
|
47
|
+
Wait-Event -SourceIdentifier "LastMsgReceived" -Timeout 60 | Out-Null
|
48
|
+
|
49
|
+
$process.CancelOutputRead()
|
50
|
+
$process.CancelErrorRead()
|
51
|
+
$process.Close()
|
52
|
+
}
|
53
|
+
return $exitCode
|
54
|
+
}
|
55
|
+
|
56
|
+
exit ps-runas "<%= options[:user] %>" "<%= options[:password] %>" "<%= options[:cmd] %>" "<%= options[:arguments] %>"
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "pathname"
|
2
|
+
|
3
|
+
module VagrantWindows
|
4
|
+
|
5
|
+
def self.vagrant_lib_root
|
6
|
+
# example match: /Applications/Vagrant/embedded/gems/gems/vagrant-1.1.2/lib
|
7
|
+
@vagrant_lib_root ||= $LOAD_PATH.select { |p| p =~ /\/vagrant-[1-9].[0-9].[0-9]\/lib/ }.first
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.vagrant_root
|
11
|
+
@vagrant_root ||= Pathname.new(File.expand_path("../", vagrant_lib_root))
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.vagrant_windows_root
|
15
|
+
@vagrant_windows_root ||= Pathname.new(File.expand_path("../../", __FILE__))
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.load_script(script_file_name)
|
19
|
+
File.read(expand_script_path(script_file_name))
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.load_script_template(script_file_name, options)
|
23
|
+
Vagrant::Util::TemplateRenderer.render(expand_script_path(script_file_name), options)
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.expand_script_path(script_file_name)
|
27
|
+
File.expand_path("lib/vagrant-windows/scripts/#{script_file_name}", VagrantWindows.vagrant_windows_root)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
require "vagrant-windows/plugin"
|
data/locales/en.yml
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
en:
|
2
|
+
vagrant_windows:
|
3
|
+
|
4
|
+
errors:
|
5
|
+
winrm_port_not_detected: |-
|
6
|
+
Vagrant could not detect the WinRM port.
|
7
|
+
|
8
|
+
Host port: %{port}
|
9
|
+
Guest port: %{guest_port}
|
10
|
+
winrm_invalid_shell: |-
|
11
|
+
%{shell} is not a supported type of Windows shell.
|
12
|
+
winrm_execution_error: |-
|
13
|
+
An error occurred executing a remote WinRM command.
|
14
|
+
|
15
|
+
Shell: %{shell}
|
16
|
+
Command: %{command}
|
17
|
+
Message: %{message}
|
18
|
+
winrm_bad_exit_status: |-
|
19
|
+
The remote command returned a bad exit status of %{exit_status}.
|
20
|
+
|
21
|
+
Shell: %{shell}
|
22
|
+
Command: %{command}
|
23
|
+
winrm_auth_error: |-
|
24
|
+
An authorization error occurred connecting to WinRM.
|
25
|
+
|
26
|
+
User: %{user}
|
27
|
+
Password: %{password}
|
28
|
+
Endpoint: %{endpoint}
|
29
|
+
Message: %{message}
|