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