vagrant-plugin-dummy 0.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.
- data/.gitignore +20 -0
- data/Gemfile +11 -0
- data/README.md +24 -0
- data/Rakefile +15 -0
- data/lib/vagrant-plugin-dummy/communication/communicator.rb +51 -0
- data/lib/vagrant-plugin-dummy/errors.rb +13 -0
- data/lib/vagrant-plugin-dummy/guest/dummy.rb +48 -0
- data/lib/vagrant-plugin-dummy/monkey_patches/lib/vagrant/machine.rb +27 -0
- data/lib/vagrant-plugin-dummy/plugin.rb +100 -0
- data/lib/vagrant-plugin-dummy/version.rb +3 -0
- data/lib/vagrant-plugin-dummy.rb +24 -0
- data/locales/en.yml +8 -0
- data/oldgit/FETCH_HEAD +4 -0
- data/oldgit/HEAD +1 -0
- data/oldgit/ORIG_HEAD +1 -0
- data/oldgit/config +12 -0
- data/oldgit/description +1 -0
- data/oldgit/hooks/applypatch-msg.sample +15 -0
- data/oldgit/hooks/commit-msg.sample +24 -0
- data/oldgit/hooks/post-update.sample +8 -0
- data/oldgit/hooks/pre-applypatch.sample +14 -0
- data/oldgit/hooks/pre-commit.sample +50 -0
- data/oldgit/hooks/pre-rebase.sample +169 -0
- data/oldgit/hooks/prepare-commit-msg.sample +36 -0
- data/oldgit/hooks/update.sample +128 -0
- data/oldgit/index +0 -0
- data/oldgit/info/exclude +6 -0
- data/oldgit/logs/HEAD +13 -0
- data/oldgit/logs/refs/heads/dummy-master +1 -0
- data/oldgit/logs/refs/heads/master +2 -0
- data/oldgit/logs/refs/heads/vagrant-1.2 +3 -0
- data/oldgit/logs/refs/remotes/origin/HEAD +1 -0
- data/oldgit/logs/refs/remotes/origin/chef-schtasks +1 -0
- data/oldgit/logs/refs/remotes/origin/master +2 -0
- data/oldgit/logs/refs/remotes/origin/vagrant-1.2 +3 -0
- data/oldgit/logs/refs/remotes/origin/winrm-2.0 +1 -0
- data/oldgit/objects/pack/pack-829e113048479ca488917c38a7779511189ee623.idx +0 -0
- data/oldgit/objects/pack/pack-829e113048479ca488917c38a7779511189ee623.pack +0 -0
- data/oldgit/objects/pack/pack-9d783f03b5d312d0eb7c60c232336524cf240841.idx +0 -0
- data/oldgit/objects/pack/pack-9d783f03b5d312d0eb7c60c232336524cf240841.pack +0 -0
- data/oldgit/objects/pack/pack-fc30e147a30fce4b4b0e300c3cdb4743945456d4.idx +0 -0
- data/oldgit/objects/pack/pack-fc30e147a30fce4b4b0e300c3cdb4743945456d4.pack +0 -0
- data/oldgit/packed-refs +9 -0
- data/oldgit/refs/heads/dummy-master +1 -0
- data/oldgit/refs/heads/master +1 -0
- data/oldgit/refs/heads/vagrant-1.2 +1 -0
- data/oldgit/refs/remotes/origin/chef-schtasks +1 -0
- data/oldgit/refs/remotes/origin/master +1 -0
- data/oldgit/refs/remotes/origin/vagrant-1.2 +1 -0
- data/oldgit/refs/remotes/origin/winrm-2.0 +1 -0
- data/spec/vagrant-windows/config_spec.rb +58 -0
- data/spec/vagrant-windows/guestnetwork_spec.rb +48 -0
- data/spec/vagrant-windows/helper_spec.rb +38 -0
- data/spec/vagrant-windows/winrmcommunicator_spec.rb +27 -0
- data/vagrant-plugin-dummy.gemspec +53 -0
- data/windows/communication/guestnetwork.rb +133 -0
- data/windows/communication/winrmcommunicator.rb +120 -0
- data/windows/communication/winrmfinder.rb +45 -0
- data/windows/communication/winrmshell.rb +141 -0
- data/windows/config/windows.rb +35 -0
- data/windows/config/winrm.rb +51 -0
- data/windows/errors.rb +27 -0
- data/windows/guest/cap/change_host_name.rb +14 -0
- data/windows/guest/cap/configure_networks.rb +69 -0
- data/windows/guest/cap/halt.rb +22 -0
- data/windows/guest/cap/mount_virtualbox_shared_folder.rb +17 -0
- data/windows/guest/cap/mount_vmware_shared_folder.rb +15 -0
- data/windows/guest/windows.rb +71 -0
- data/windows/helper.rb +19 -0
- data/windows/monkey_patches/lib/vagrant/machine.rb +32 -0
- data/windows/monkey_patches/plugins/providers/virtualbox/action/share_folders.rb +44 -0
- data/windows/monkey_patches/plugins/providers/virtualbox/driver/version_4_2.rb +20 -0
- data/windows/monkey_patches/plugins/provisioners/chef/provisioner/chef_client.rb +1 -0
- data/windows/monkey_patches/plugins/provisioners/chef/provisioner/chef_solo.rb +106 -0
- data/windows/monkey_patches/plugins/provisioners/puppet/provisioner/puppet.rb +101 -0
- data/windows/monkey_patches/plugins/provisioners/puppet/provisioner/puppet_server.rb +1 -0
- data/windows/monkey_patches/plugins/provisioners/shell/provisioner.rb +89 -0
- data/windows/plugin.rb +129 -0
- data/windows/scripts/cheftask.ps1.erb +47 -0
- data/windows/scripts/cheftask.xml.erb +45 -0
- data/windows/scripts/cheftaskrun.ps1.erb +16 -0
- data/windows/scripts/command_alias.ps1 +36 -0
- data/windows/scripts/mount_volume.virtualbox.ps1.erb +49 -0
- data/windows/scripts/mount_volume.vmware.ps1.erb +49 -0
- data/windows/scripts/set_work_network.ps1 +6 -0
- data/windows/scripts/winrs_v3_get_adapters.ps1 +11 -0
- data/windows/version.rb +3 -0
- metadata +207 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
require 'timeout'
|
|
2
|
+
require 'log4r'
|
|
3
|
+
require_relative '../errors'
|
|
4
|
+
require_relative 'winrmshell'
|
|
5
|
+
require_relative 'winrmfinder'
|
|
6
|
+
|
|
7
|
+
module VagrantWindows
|
|
8
|
+
module Communication
|
|
9
|
+
# Provides communication with the VM via WinRM.
|
|
10
|
+
class WinRMCommunicator < Vagrant.plugin("2", :communicator)
|
|
11
|
+
|
|
12
|
+
attr_reader :logger
|
|
13
|
+
attr_reader :machine
|
|
14
|
+
attr_reader :winrm_finder
|
|
15
|
+
|
|
16
|
+
def self.match?(machine)
|
|
17
|
+
machine.config.vm.guest.eql? :windows
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize(machine)
|
|
21
|
+
@machine = machine
|
|
22
|
+
@logger = Log4r::Logger.new("vagrant_windows::communication::winrmcommunicator")
|
|
23
|
+
@logger.debug("initializing WinRMCommunicator")
|
|
24
|
+
@winrm_finder = WinRMFinder.new(machine)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def ready?
|
|
28
|
+
logger.debug("Checking whether WinRM is ready...")
|
|
29
|
+
|
|
30
|
+
Timeout.timeout(@machine.config.winrm.timeout) do
|
|
31
|
+
session.powershell("hostname")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
logger.info("WinRM is ready!")
|
|
35
|
+
return true
|
|
36
|
+
|
|
37
|
+
rescue Vagrant::Errors::VagrantError => e
|
|
38
|
+
# We catch a `VagrantError` which would signal that something went
|
|
39
|
+
# wrong expectedly in the `connect`, which means we didn't connect.
|
|
40
|
+
@logger.info("WinRM not up: #{e.inspect}")
|
|
41
|
+
return false
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def execute(command, opts={}, &block)
|
|
45
|
+
if opts[:shell].eql? :cmd
|
|
46
|
+
session.cmd(command, &block)[:exitcode]
|
|
47
|
+
else
|
|
48
|
+
command = VagrantWindows.load_script("command_alias.ps1") << "\r\n" << command
|
|
49
|
+
session.powershell(command, &block)[:exitcode]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
alias_method :sudo, :execute
|
|
53
|
+
|
|
54
|
+
def test(command, opts=nil)
|
|
55
|
+
# HACK: to speed up Vagrant 1.2 OS detection, skip checking for *nix OS
|
|
56
|
+
return false unless (command =~ /^uname|^cat \/etc|^cat \/proc|grep 'Fedora/).nil?
|
|
57
|
+
execute(command) == 0
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def upload(from, to)
|
|
61
|
+
@logger.debug("Uploading: #{from} to #{to}")
|
|
62
|
+
file = "winrm-upload-#{rand()}"
|
|
63
|
+
file_name = (session.cmd("echo %TEMP%\\#{file}"))[:data][0][:stdout].chomp
|
|
64
|
+
session.powershell <<-EOH
|
|
65
|
+
if(Test-Path #{to})
|
|
66
|
+
{
|
|
67
|
+
rm #{to}
|
|
68
|
+
}
|
|
69
|
+
EOH
|
|
70
|
+
Base64.encode64(IO.binread(from)).gsub("\n",'').chars.to_a.each_slice(8000-file_name.size) do |chunk|
|
|
71
|
+
out = session.cmd("echo #{chunk.join} >> \"#{file_name}\"")
|
|
72
|
+
end
|
|
73
|
+
session.powershell("mkdir $([System.IO.Path]::GetDirectoryName(\"#{to}\"))")
|
|
74
|
+
session.powershell <<-EOH
|
|
75
|
+
$base64_string = Get-Content \"#{file_name}\"
|
|
76
|
+
$bytes = [System.Convert]::FromBase64String($base64_string)
|
|
77
|
+
$new_file = [System.IO.Path]::GetFullPath(\"#{to}\")
|
|
78
|
+
[System.IO.File]::WriteAllBytes($new_file,$bytes)
|
|
79
|
+
EOH
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def download(from, to=nil)
|
|
83
|
+
@logger.warn("Downloading: #{from} to #{to} not supported on Windows guests")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Runs a remote WQL query against the VM
|
|
87
|
+
#
|
|
88
|
+
# Note: This is not part of the standard Vagrant communicator interface, but
|
|
89
|
+
# guest capabilities may need to use this.
|
|
90
|
+
def wql(query)
|
|
91
|
+
session.wql(query)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def set_winrmshell(winrmshell)
|
|
95
|
+
@session = winrmshell
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def session
|
|
99
|
+
@session ||= new_session
|
|
100
|
+
end
|
|
101
|
+
alias_method :winrmshell, :session
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
protected
|
|
105
|
+
|
|
106
|
+
def new_session
|
|
107
|
+
WinRMShell.new(
|
|
108
|
+
@winrm_finder.winrm_host_address(),
|
|
109
|
+
@machine.config.winrm.username,
|
|
110
|
+
@machine.config.winrm.password,
|
|
111
|
+
{
|
|
112
|
+
:port => @winrm_finder.winrm_host_port(),
|
|
113
|
+
:timeout_in_seconds => @machine.config.winrm.timeout,
|
|
114
|
+
:max_tries => @machine.config.winrm.max_tries
|
|
115
|
+
})
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
end #WinRM class
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
require_relative '../errors'
|
|
3
|
+
|
|
4
|
+
module VagrantWindows
|
|
5
|
+
module Communication
|
|
6
|
+
class WinRMFinder
|
|
7
|
+
|
|
8
|
+
attr_reader :logger
|
|
9
|
+
attr_reader :machine
|
|
10
|
+
|
|
11
|
+
def initialize(machine)
|
|
12
|
+
@machine = machine
|
|
13
|
+
@logger = Log4r::Logger.new("vagrant_windows::communication::winrmfinder")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def winrm_host_address
|
|
17
|
+
# Get the SSH info for the machine, raise an exception if the
|
|
18
|
+
# provider is saying that SSH is not ready.
|
|
19
|
+
ssh_info = @machine.ssh_info
|
|
20
|
+
raise Vagrant::Errors::SSHNotReady if ssh_info.nil?
|
|
21
|
+
@logger.info("WinRM host: #{ssh_info[:host]}")
|
|
22
|
+
return ssh_info[:host]
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def winrm_host_port
|
|
26
|
+
expected_guest_port = @machine.config.winrm.guest_port
|
|
27
|
+
@logger.debug("Searching for WinRM port: #{expected_guest_port.inspect}")
|
|
28
|
+
|
|
29
|
+
# Look for the forwarded port only by comparing the guest port
|
|
30
|
+
begin
|
|
31
|
+
@machine.provider.driver.read_forwarded_ports.each do |_, _, hostport, guestport|
|
|
32
|
+
return hostport if guestport == expected_guest_port
|
|
33
|
+
end
|
|
34
|
+
rescue NoMethodError => e
|
|
35
|
+
# VMWare provider doesn't support read_forwarded_ports
|
|
36
|
+
@logger.debug(e.message)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# We tried, give up and use the configured port as-is
|
|
40
|
+
@machine.config.winrm.port
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
require 'timeout'
|
|
2
|
+
require 'log4r'
|
|
3
|
+
require 'winrm'
|
|
4
|
+
require 'vagrant/util/retryable'
|
|
5
|
+
require_relative '../errors'
|
|
6
|
+
|
|
7
|
+
module VagrantWindows
|
|
8
|
+
module Communication
|
|
9
|
+
class WinRMShell
|
|
10
|
+
|
|
11
|
+
include Vagrant::Util::Retryable
|
|
12
|
+
|
|
13
|
+
# These are the exceptions that we retry because they represent
|
|
14
|
+
# errors that are generally fixed from a retry and don't
|
|
15
|
+
# necessarily represent immediate failure cases.
|
|
16
|
+
@@exceptions_to_retry_on = [
|
|
17
|
+
HTTPClient::KeepAliveDisconnected,
|
|
18
|
+
WinRM::WinRMHTTPTransportError,
|
|
19
|
+
Errno::EACCES,
|
|
20
|
+
Errno::EADDRINUSE,
|
|
21
|
+
Errno::ECONNREFUSED,
|
|
22
|
+
Errno::ECONNRESET,
|
|
23
|
+
Errno::ENETUNREACH,
|
|
24
|
+
Errno::EHOSTUNREACH,
|
|
25
|
+
Timeout::Error
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
attr_reader :logger
|
|
29
|
+
attr_reader :username
|
|
30
|
+
attr_reader :password
|
|
31
|
+
attr_reader :host
|
|
32
|
+
attr_reader :port
|
|
33
|
+
attr_reader :timeout_in_seconds
|
|
34
|
+
attr_reader :max_tries
|
|
35
|
+
|
|
36
|
+
def initialize(host, username, password, options = {})
|
|
37
|
+
@logger = Log4r::Logger.new("vagrant_windows::communication::winrmshell")
|
|
38
|
+
@logger.debug("initializing WinRMShell")
|
|
39
|
+
|
|
40
|
+
@host = host
|
|
41
|
+
@port = options[:port] || 5985
|
|
42
|
+
@username = username
|
|
43
|
+
@password = password
|
|
44
|
+
@timeout_in_seconds = options[:timeout_in_seconds] || 60
|
|
45
|
+
@max_tries = options[:max_tries] || 20
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def powershell(command, &block)
|
|
49
|
+
execute_shell(command, :powershell, &block)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def cmd(command, &block)
|
|
53
|
+
execute_shell(command, :cmd, &block)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def wql(query)
|
|
57
|
+
execute_wql(query)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
protected
|
|
61
|
+
|
|
62
|
+
def execute_shell(command, shell=:powershell, &block)
|
|
63
|
+
retryable(:tries => @max_tries, :on => @@exceptions_to_retry_on, :sleep => 10) do
|
|
64
|
+
@logger.debug("#{shell} executing:\n#{command}")
|
|
65
|
+
if shell.eql? :cmd
|
|
66
|
+
output = session.cmd(command) do |out, err|
|
|
67
|
+
block.call(:stdout, out) if block_given? && out
|
|
68
|
+
block.call(:stderr, err) if block_given? && err
|
|
69
|
+
end
|
|
70
|
+
elsif shell.eql? :powershell
|
|
71
|
+
output = session.powershell(command) do |out, err|
|
|
72
|
+
block.call(:stdout, out) if block_given? && out
|
|
73
|
+
block.call(:stderr, err) if block_given? && err
|
|
74
|
+
end
|
|
75
|
+
else
|
|
76
|
+
raise Errors::WinRMInvalidShell, :shell => shell
|
|
77
|
+
end
|
|
78
|
+
@logger.debug("Exit status: #{output[:exitcode].inspect}")
|
|
79
|
+
return output
|
|
80
|
+
end
|
|
81
|
+
rescue => e
|
|
82
|
+
handle_winrm_exception(e, shell, command)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def execute_wql(query)
|
|
86
|
+
retryable(:tries => @max_tries, :on => @@exceptions_to_retry_on, :sleep => 10) do
|
|
87
|
+
@logger.debug("#executing wql: #{query}")
|
|
88
|
+
output = session.wql(query)
|
|
89
|
+
@logger.debug("wql result: #{output.inspect}")
|
|
90
|
+
return output
|
|
91
|
+
end
|
|
92
|
+
rescue => e
|
|
93
|
+
handle_winrm_exception(e, :wql, query)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def handle_winrm_exception(winrm_exception, shell, command)
|
|
97
|
+
if winrm_exception.message.include?("401") # return a more specific auth error for 401 errors
|
|
98
|
+
raise Errors::WinRMAuthorizationError,
|
|
99
|
+
:user => @username,
|
|
100
|
+
:password => @password,
|
|
101
|
+
:endpoint => endpoint,
|
|
102
|
+
:message => winrm_exception.message
|
|
103
|
+
end
|
|
104
|
+
raise Errors::WinRMExecutionError,
|
|
105
|
+
:shell => shell,
|
|
106
|
+
:command => command,
|
|
107
|
+
:message => winrm_exception.message
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def new_session
|
|
111
|
+
@logger.info("Attempting to connect to WinRM...")
|
|
112
|
+
@logger.info(" - Host: #{@host}")
|
|
113
|
+
@logger.info(" - Port: #{@port}")
|
|
114
|
+
@logger.info(" - Username: #{@username}")
|
|
115
|
+
|
|
116
|
+
client = ::WinRM::WinRMWebService.new(endpoint, :plaintext, endpoint_options)
|
|
117
|
+
client.set_timeout(@timeout_in_seconds)
|
|
118
|
+
client.toggle_nori_type_casting(:off) #we don't want coersion of types
|
|
119
|
+
client
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def session
|
|
123
|
+
@session ||= new_session
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def endpoint
|
|
127
|
+
"http://#{@host}:#{@port}/wsman"
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def endpoint_options
|
|
131
|
+
{ :user => @username,
|
|
132
|
+
:pass => @password,
|
|
133
|
+
:host => @host,
|
|
134
|
+
:port => @port,
|
|
135
|
+
:operation_timeout => @timeout_in_seconds,
|
|
136
|
+
:basic_auth_only => true }
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
end #WinShell class
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require "vagrant"
|
|
2
|
+
|
|
3
|
+
module VagrantWindows
|
|
4
|
+
module Config
|
|
5
|
+
class Windows < Vagrant.plugin("2", :config)
|
|
6
|
+
|
|
7
|
+
attr_accessor :halt_timeout
|
|
8
|
+
attr_accessor :halt_check_interval
|
|
9
|
+
attr_accessor :set_work_network
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@halt_timeout = UNSET_VALUE
|
|
13
|
+
@halt_check_interval = UNSET_VALUE
|
|
14
|
+
@set_work_network = UNSET_VALUE
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def validate(machine)
|
|
18
|
+
errors = []
|
|
19
|
+
|
|
20
|
+
errors << "windows.halt_timeout cannot be nil." if machine.config.windows.halt_timeout.nil?
|
|
21
|
+
errors << "windows.halt_check_interval cannot be nil." if machine.config.windows.halt_check_interval.nil?
|
|
22
|
+
|
|
23
|
+
errors << "windows.set_work_network cannot be nil." if machine.config.windows.set_work_network.nil?
|
|
24
|
+
{ "Windows Guest" => errors }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def finalize!
|
|
28
|
+
@halt_timeout = 30 if @halt_timeout == UNSET_VALUE
|
|
29
|
+
@halt_check_interval = 1 if @halt_check_interval == UNSET_VALUE
|
|
30
|
+
@set_work_network = false if @set_work_network == UNSET_VALUE
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require "vagrant"
|
|
2
|
+
|
|
3
|
+
module VagrantWindows
|
|
4
|
+
module Config
|
|
5
|
+
class WinRM < Vagrant.plugin("2", :config)
|
|
6
|
+
|
|
7
|
+
attr_accessor :username
|
|
8
|
+
attr_accessor :password
|
|
9
|
+
attr_accessor :host
|
|
10
|
+
attr_accessor :port
|
|
11
|
+
attr_accessor :guest_port
|
|
12
|
+
attr_accessor :max_tries
|
|
13
|
+
attr_accessor :timeout
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
@username = UNSET_VALUE
|
|
17
|
+
@password = UNSET_VALUE
|
|
18
|
+
@host = UNSET_VALUE
|
|
19
|
+
@port = UNSET_VALUE
|
|
20
|
+
@guest_port = UNSET_VALUE
|
|
21
|
+
@max_tries = UNSET_VALUE
|
|
22
|
+
@timeout = UNSET_VALUE
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def validate(machine)
|
|
26
|
+
errors = []
|
|
27
|
+
|
|
28
|
+
errors << "winrm.username cannot be nil." if machine.config.winrm.username.nil?
|
|
29
|
+
errors << "winrm.password cannot be nil." if machine.config.winrm.password.nil?
|
|
30
|
+
errors << "winrm.host cannot be nil." if machine.config.winrm.host.nil?
|
|
31
|
+
errors << "winrm.port cannot be nil." if machine.config.winrm.port.nil?
|
|
32
|
+
errors << "winrm.guest_port cannot be nil." if machine.config.winrm.guest_port.nil?
|
|
33
|
+
errors << "winrm.max_tries cannot be nil." if machine.config.winrm.max_tries.nil?
|
|
34
|
+
errors << "winrm.timeout cannot be nil." if machine.config.winrm.timeout.nil?
|
|
35
|
+
|
|
36
|
+
{ "WinRM" => errors }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def finalize!
|
|
40
|
+
@username = "vagrant" if @username == UNSET_VALUE
|
|
41
|
+
@password = "vagrant" if @password == UNSET_VALUE
|
|
42
|
+
@host = "localhost" if @host == UNSET_VALUE
|
|
43
|
+
@port = 5985 if @port == UNSET_VALUE
|
|
44
|
+
@guest_port = 5985 if @guest_port == UNSET_VALUE
|
|
45
|
+
@max_tries = 20 if @max_tries == UNSET_VALUE
|
|
46
|
+
@timeout = 1800 if @timeout == UNSET_VALUE
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/windows/errors.rb
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'vagrant/errors'
|
|
2
|
+
|
|
3
|
+
module VagrantWindows
|
|
4
|
+
module Errors
|
|
5
|
+
|
|
6
|
+
class VagrantWindowsError < ::Vagrant::Errors::VagrantError
|
|
7
|
+
error_namespace("vagrant_windows.errors")
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class WinRMPortNotDetected < VagrantWindowsError
|
|
11
|
+
error_key(:winrm_port_not_detected)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class WinRMInvalidShell < VagrantWindowsError
|
|
15
|
+
error_key(:winrm_invalid_shell)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class WinRMExecutionError < VagrantWindowsError
|
|
19
|
+
error_key(:winrm_execution_error)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class WinRMAuthorizationError < VagrantWindowsError
|
|
23
|
+
error_key(:winrm_auth_error)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module VagrantWindows
|
|
2
|
+
module Guest
|
|
3
|
+
module Cap
|
|
4
|
+
class ChangeHostName
|
|
5
|
+
def self.change_host_name(machine, name)
|
|
6
|
+
#### on windows, renaming a computer seems to require a reboot
|
|
7
|
+
machine.communicate.execute(
|
|
8
|
+
"wmic computersystem where name=\"%COMPUTERNAME%\" call rename name=\"#{name}\"",
|
|
9
|
+
:shell => :cmd)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
require 'log4r'
|
|
2
|
+
require_relative '../../communication/guestnetwork'
|
|
3
|
+
require_relative '../../communication/winrmshell'
|
|
4
|
+
require_relative '../../errors'
|
|
5
|
+
|
|
6
|
+
module VagrantWindows
|
|
7
|
+
module Guest
|
|
8
|
+
module Cap
|
|
9
|
+
class ConfigureNetworks
|
|
10
|
+
|
|
11
|
+
@@logger = Log4r::Logger.new("vagrant_windows::guest::cap::configure_networks")
|
|
12
|
+
|
|
13
|
+
def self.configure_networks(machine, networks)
|
|
14
|
+
@@logger.debug("networks: #{networks.inspect}")
|
|
15
|
+
|
|
16
|
+
guest_network = ::VagrantWindows::Communication::GuestNetwork.new(machine.communicate.winrmshell)
|
|
17
|
+
|
|
18
|
+
if (machine.provider_name != :vmware_fusion) && (machine.provider_name != :vmware_workstation)
|
|
19
|
+
vm_interface_map = create_vm_interface_map(machine, guest_network)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
networks.each do |network|
|
|
23
|
+
interface = vm_interface_map[network[:interface]+1]
|
|
24
|
+
if interface.nil?
|
|
25
|
+
@@logger.warn("Could not find interface for network #{network.inspect}")
|
|
26
|
+
next
|
|
27
|
+
end
|
|
28
|
+
network_type = network[:type].to_sym
|
|
29
|
+
if network_type == :static
|
|
30
|
+
guest_network.configure_static_interface(
|
|
31
|
+
interface[:index],
|
|
32
|
+
interface[:net_connection_id],
|
|
33
|
+
network[:ip],
|
|
34
|
+
network[:netmask])
|
|
35
|
+
elsif network_type == :dhcp
|
|
36
|
+
guest_network.configure_dhcp_interface(
|
|
37
|
+
interface[:index],
|
|
38
|
+
interface[:net_connection_id])
|
|
39
|
+
else
|
|
40
|
+
raise WindowsError, "#{network_type} network type is not supported, try static or dhcp"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
guest_network.set_all_networks_to_work() if machine.config.windows.set_work_network
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#{1=>{:name=>"Local Area Connection", :mac_address=>"0800275FAC5B", :interface_index=>"11", :index=>"7"}}
|
|
47
|
+
def self.create_vm_interface_map(machine, guest_network)
|
|
48
|
+
vm_interface_map = {}
|
|
49
|
+
driver_mac_address = machine.provider.driver.read_mac_addresses.invert
|
|
50
|
+
@@logger.debug("mac addresses: #{driver_mac_address.inspect}")
|
|
51
|
+
guest_network.network_adapters().each do |nic|
|
|
52
|
+
@@logger.debug("nic: #{nic.inspect}")
|
|
53
|
+
naked_mac = nic[:mac_address].gsub(':','')
|
|
54
|
+
if driver_mac_address[naked_mac]
|
|
55
|
+
vm_interface_map[driver_mac_address[naked_mac]] = {
|
|
56
|
+
:name => nic[:net_connection_id],
|
|
57
|
+
:mac_address => naked_mac,
|
|
58
|
+
:interface_index => nic[:interface_index],
|
|
59
|
+
:index => nic[:index] }
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
@@logger.debug("vm_interface_map: #{vm_interface_map.inspect}")
|
|
63
|
+
vm_interface_map
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
module VagrantWindows
|
|
2
|
+
module Guest
|
|
3
|
+
module Cap
|
|
4
|
+
class Halt
|
|
5
|
+
def self.halt(machine)
|
|
6
|
+
machine.communicate.execute("shutdown /s /t 1 /c \"Vagrant Halt\" /f /d p:4:1")
|
|
7
|
+
|
|
8
|
+
# Wait until the VM's state is actually powered off. If this doesn't
|
|
9
|
+
# occur within a reasonable amount of time (15 seconds by default),
|
|
10
|
+
# then simply return and allow Vagrant to kill the machine.
|
|
11
|
+
count = 0
|
|
12
|
+
while machine.state != :poweroff
|
|
13
|
+
count += 1
|
|
14
|
+
|
|
15
|
+
return if count >= machine.config.windows.halt_timeout
|
|
16
|
+
sleep machine.config.windows.halt_check_interval
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require_relative '../../helper'
|
|
2
|
+
|
|
3
|
+
module VagrantWindows
|
|
4
|
+
module Guest
|
|
5
|
+
module Cap
|
|
6
|
+
class MountVirtualBoxSharedFolder
|
|
7
|
+
|
|
8
|
+
def self.mount_virtualbox_shared_folder(machine, name, guestpath, options)
|
|
9
|
+
share_name = VagrantWindows::Helper.win_friendly_share_id(name)
|
|
10
|
+
mount_script = VagrantWindows.load_script_template("mount_volume.virtualbox.ps1",
|
|
11
|
+
:options => {:mount_point => guestpath, :share_name => share_name})
|
|
12
|
+
machine.communicate.execute(mount_script, {:shell => :powershell})
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module VagrantWindows
|
|
2
|
+
module Guest
|
|
3
|
+
module Cap
|
|
4
|
+
class MountVMwareSharedFolder
|
|
5
|
+
|
|
6
|
+
def self.mount_vmware_shared_folder(machine, name, guestpath, options)
|
|
7
|
+
share_name = VagrantWindows::Helper.win_friendly_share_id(name)
|
|
8
|
+
mount_script = VagrantWindows.load_script_template("mount_volume.vmware.ps1",
|
|
9
|
+
:options => {:mount_point => guestpath, :share_name => share_name})
|
|
10
|
+
machine.communicate.execute(mount_script, {:shell => :powershell})
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require "vagrant"
|
|
2
|
+
require "vagrant-windows/guest/cap/change_host_name"
|
|
3
|
+
require "vagrant-windows/guest/cap/configure_networks"
|
|
4
|
+
require "vagrant-windows/guest/cap/halt"
|
|
5
|
+
require "vagrant-windows/guest/cap/mount_virtualbox_shared_folder"
|
|
6
|
+
require "vagrant-windows/guest/cap/mount_vmware_shared_folder"
|
|
7
|
+
|
|
8
|
+
module VagrantWindows
|
|
9
|
+
module Guest
|
|
10
|
+
class Windows < Vagrant.plugin("2", :guest)
|
|
11
|
+
|
|
12
|
+
# Vagrant 1.1.x compatibibility methods
|
|
13
|
+
# Implement the 1.1.x methods and call through to the new 1.2.x capabilities
|
|
14
|
+
|
|
15
|
+
attr_reader :machine
|
|
16
|
+
|
|
17
|
+
def initialize(machine = nil)
|
|
18
|
+
super(machine) unless machine == nil
|
|
19
|
+
@machine = machine
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def change_host_name(name)
|
|
23
|
+
VagrantWindows::Guest::Cap::ChangeHostName.change_host_name(@machine, name)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def distro_dispatch
|
|
27
|
+
:windows
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def halt
|
|
31
|
+
VagrantWindows::Guest::Cap::Halt.halt(@machine)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def mount_virtualbox_shared_folder(name, guestpath, options)
|
|
35
|
+
VagrantWindows::Guest::Cap::MountVirtualBoxSharedFolder.mount_virtualbox_shared_folder(
|
|
36
|
+
@machine, name, guestpath, options)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def mount_vmware_shared_folder(name, guestpath, options)
|
|
40
|
+
VagrantWindows::Guest::Cap::MountVMwareBoxSharedFolder.mount_vmware_shared_folder(
|
|
41
|
+
@machine, name, guestpath, options)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def configure_networks(networks)
|
|
45
|
+
VagrantWindows::Guest::Cap::ConfigureNetworks.configure_networks(@machine, networks)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# Vagrant 1.2.x compatibibility methods
|
|
50
|
+
|
|
51
|
+
def detect?(machine)
|
|
52
|
+
|
|
53
|
+
# uname -o | grep Solaris
|
|
54
|
+
# uname -s | grep 'Linux'
|
|
55
|
+
# uname -s | grep 'FreeBSD'
|
|
56
|
+
# cat /etc/redhat-release
|
|
57
|
+
# uname -s | grep 'OpenBSD'
|
|
58
|
+
# cat /etc/gentoo-release
|
|
59
|
+
# cat /proc/version | grep 'Debian'
|
|
60
|
+
# cat /etc/arch-release
|
|
61
|
+
# cat /proc/version | grep 'Ubuntu'
|
|
62
|
+
# cat /etc/SuSE-release
|
|
63
|
+
# cat /etc/pld-release
|
|
64
|
+
# grep 'Fedora release 1[678]' /etc/redhat-release
|
|
65
|
+
|
|
66
|
+
# see if the Windows directory is present
|
|
67
|
+
machine.communicate.test("test -d $Env:SystemRoot")
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
data/windows/helper.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module VagrantWindows
|
|
2
|
+
module Helper
|
|
3
|
+
extend self
|
|
4
|
+
|
|
5
|
+
def win_friendly_path(path)
|
|
6
|
+
if path
|
|
7
|
+
new_path = path.gsub('/', '\\')
|
|
8
|
+
new_path = "c:#{new_path}" if new_path =~ /^\\/
|
|
9
|
+
end
|
|
10
|
+
new_path
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# turns '/vagrant' into 'vagrant' or turns ''/a/b/c/d/e' into 'a_b_c_d_e'
|
|
14
|
+
def win_friendly_share_id(shared_folder_name)
|
|
15
|
+
return shared_folder_name.gsub(/[\/\/]/,'_').sub(/^_/, '')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require_relative '../../../helper'
|
|
2
|
+
require_relative '../../../communication/winrmcommunicator'
|
|
3
|
+
|
|
4
|
+
module Vagrant
|
|
5
|
+
class Machine
|
|
6
|
+
|
|
7
|
+
ssh_communicate = instance_method(:communicate)
|
|
8
|
+
|
|
9
|
+
# This patch is needed until Vagrant supports a configurable communication channel
|
|
10
|
+
define_method(:communicate) do
|
|
11
|
+
unless @communicator
|
|
12
|
+
if @config.vm.guest.eql? :windows
|
|
13
|
+
@logger.info("guest is #{@config.vm.guest}, using WinRM for communication channel")
|
|
14
|
+
@communicator = ::VagrantWindows::Communication::WinRMCommunicator.new(self)
|
|
15
|
+
else
|
|
16
|
+
@logger.info("guest is #{@config.vm.guest}, using SSH for communication channel")
|
|
17
|
+
@communicator = ssh_communicate.bind(self).()
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
@communicator
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def winrm
|
|
24
|
+
@winrm ||= WinRM.new(self)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def is_windows?
|
|
28
|
+
return @config.vm.guest.eql? :windows
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
end
|
|
32
|
+
end
|