vagrant-windows 1.6.0 → 1.7.0.pre.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -1
  3. data/CHANGELOG.md +7 -1
  4. data/Gemfile +5 -1
  5. data/README.md +3 -1
  6. data/lib/vagrant-windows/communication/command_filters/cat.rb +27 -0
  7. data/lib/vagrant-windows/communication/command_filters/chmod.rb +21 -0
  8. data/lib/vagrant-windows/communication/command_filters/chown.rb +21 -0
  9. data/lib/vagrant-windows/communication/command_filters/rm.rb +28 -0
  10. data/lib/vagrant-windows/communication/command_filters/test.rb +37 -0
  11. data/lib/vagrant-windows/communication/command_filters/uname.rb +36 -0
  12. data/lib/vagrant-windows/communication/command_filters/which.rb +26 -0
  13. data/lib/vagrant-windows/communication/guestnetwork.rb +16 -19
  14. data/lib/vagrant-windows/communication/linux_command_filter.rb +44 -0
  15. data/lib/vagrant-windows/communication/winrmcommunicator.rb +21 -24
  16. data/lib/vagrant-windows/communication/winrmfilemanager.rb +166 -0
  17. data/lib/vagrant-windows/communication/winrmshell.rb +8 -38
  18. data/lib/vagrant-windows/config/windows.rb +5 -5
  19. data/lib/vagrant-windows/errors.rb +5 -1
  20. data/lib/vagrant-windows/guest/cap/configure_networks.rb +1 -1
  21. data/lib/vagrant-windows/monkey_patches/plugins/provisioners/chef/provisioner/chef_client.rb +2 -5
  22. data/lib/vagrant-windows/monkey_patches/plugins/provisioners/chef/provisioner/chef_solo.rb +2 -5
  23. data/lib/vagrant-windows/monkey_patches/plugins/provisioners/shell/provisioner.rb +13 -6
  24. data/lib/vagrant-windows/provisioners/chef_command_builder.rb +7 -53
  25. data/lib/vagrant-windows/scripts/elevated_shell.ps1.erb +95 -0
  26. data/lib/vagrant-windows/version.rb +1 -1
  27. data/locales/en.yml +7 -0
  28. data/spec/vagrant-windows/chef_command_builder_spec.rb +7 -53
  29. data/spec/vagrant-windows/guestnetwork_spec.rb +10 -5
  30. data/spec/vagrant-windows/linux_command_filter_spec.rb +73 -0
  31. data/spec/vagrant-windows/winrmcommunicator_spec.rb +55 -6
  32. data/spec/vagrant-windows/winrmshell_spec.rb +12 -5
  33. metadata +16 -8
  34. data/lib/vagrant-windows/scripts/cheftask.ps1.erb +0 -48
  35. data/lib/vagrant-windows/scripts/cheftask.xml.erb +0 -45
  36. data/lib/vagrant-windows/scripts/cheftaskrun.ps1.erb +0 -18
  37. data/lib/vagrant-windows/scripts/command_alias.ps1 +0 -36
@@ -53,42 +53,23 @@ module VagrantWindows
53
53
  execute_shell(command, :cmd, &block)
54
54
  end
55
55
 
56
- def wql(query)
57
- execute_wql(query)
56
+ def wql(query, &block)
57
+ execute_shell(query, :wql, &block)
58
58
  end
59
-
59
+
60
60
  def upload(from, to)
61
- @logger.debug("Uploading: #{from} to #{to}")
62
- file_name = (cmd("echo %TEMP%\\winrm-upload-#{rand()}"))[:data][0][:stdout].chomp
63
- powershell <<-EOH
64
- if(Test-Path #{to}) {
65
- rm #{to}
66
- }
67
- EOH
68
- Base64.encode64(IO.binread(from)).gsub("\n",'').chars.to_a.each_slice(8000-file_name.size) do |chunk|
69
- out = cmd("echo #{chunk.join} >> \"#{file_name}\"")
70
- end
71
- powershell <<-EOH
72
- mkdir $([System.IO.Path]::GetDirectoryName(\"#{to}\"))
73
- $base64_string = Get-Content \"#{file_name}\"
74
- $bytes = [System.Convert]::FromBase64String($base64_string)
75
- $new_file = [System.IO.Path]::GetFullPath(\"#{to}\")
76
- [System.IO.File]::WriteAllBytes($new_file,$bytes)
77
- EOH
61
+ WinRMFileManager.new(self).upload(from, to)
78
62
  end
79
63
 
80
64
  def download(from, to)
81
- @logger.debug("Downloading: #{from} to #{to}")
82
- output = powershell("[System.convert]::ToBase64String([System.IO.File]::ReadAllBytes(\"#{from}\"))")
83
- contents = output[:data].map!{|line| line[:stdout]}.join.gsub("\\n\\r", '')
84
- out = Base64.decode64(contents)
85
- IO.binwrite(to, out)
65
+ WinRMFileManager.new(self).download(from, to)
86
66
  end
87
67
 
68
+
88
69
  protected
89
70
 
90
71
  def execute_shell(command, shell=:powershell, &block)
91
- raise Errors::WinRMInvalidShell, :shell => shell unless shell == :cmd || shell == :powershell
72
+ raise Errors::WinRMInvalidShell, :shell => shell unless [:powershell, :cmd, :wql].include?(shell)
92
73
  begin
93
74
  execute_shell_with_retry(command, shell, &block)
94
75
  rescue => e
@@ -103,20 +84,9 @@ module VagrantWindows
103
84
  block.call(:stdout, out) if block_given? && out
104
85
  block.call(:stderr, err) if block_given? && err
105
86
  end
106
- @logger.debug("Exit status: #{output[:exitcode].inspect}")
107
- return output
108
- end
109
- end
110
-
111
- def execute_wql(query)
112
- retryable(:tries => @max_tries, :on => @@exceptions_to_retry_on, :sleep => 10) do
113
- @logger.debug("#executing wql: #{query}")
114
- output = session.wql(query)
115
- @logger.debug("wql result: #{output.inspect}")
87
+ @logger.debug("Output: #{output.inspect}")
116
88
  return output
117
89
  end
118
- rescue => e
119
- raise_winrm_exception(e, :wql, query)
120
90
  end
121
91
 
122
92
  def raise_winrm_exception(winrm_exception, shell, command)
@@ -17,16 +17,16 @@ module VagrantWindows
17
17
  def validate(machine)
18
18
  errors = []
19
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?
20
+ errors << "windows.halt_timeout cannot be nil." if @halt_timeout.nil?
21
+ errors << "windows.halt_check_interval cannot be nil." if @halt_check_interval.nil?
22
+ errors << "windows.set_work_network cannot be nil." if @set_work_network.nil?
22
23
 
23
- errors << "windows.set_work_network cannot be nil." if machine.config.windows.set_work_network.nil?
24
24
  { "Windows Guest" => errors }
25
25
  end
26
26
 
27
27
  def finalize!
28
- @halt_timeout = 30 if @halt_timeout == UNSET_VALUE
29
- @halt_check_interval = 1 if @halt_check_interval == UNSET_VALUE
28
+ @halt_timeout = 30 if @halt_timeout == UNSET_VALUE
29
+ @halt_check_interval = 1 if @halt_check_interval == UNSET_VALUE
30
30
  @set_work_network = false if @set_work_network == UNSET_VALUE
31
31
  end
32
32
 
@@ -21,7 +21,11 @@ module VagrantWindows
21
21
 
22
22
  class WinRMAuthorizationError < VagrantWindowsError
23
23
  error_key(:winrm_auth_error)
24
- end
24
+ end
25
+
26
+ class WinRMFileTransferError < VagrantWindowsError
27
+ error_key(:winrm_file_transfer_error)
28
+ end
25
29
 
26
30
  end
27
31
  end
@@ -16,7 +16,7 @@ module VagrantWindows
16
16
  @@logger.debug("networks: #{networks.inspect}")
17
17
 
18
18
  windows_machine = VagrantWindows::WindowsMachine.new(machine)
19
- guest_network = VagrantWindows::Communication::GuestNetwork.new(windows_machine.winrmshell)
19
+ guest_network = VagrantWindows::Communication::GuestNetwork.new(machine.communicate)
20
20
  if windows_machine.is_vmware?()
21
21
  @@logger.warn('Configuring secondary network adapters through VMware is not yet supported.')
22
22
  @@logger.warn('You will need to manually configure the network adapter.')
@@ -34,11 +34,8 @@ module VagrantPlugins
34
34
  end
35
35
 
36
36
  #################### START - monkey patched code ####################
37
- command_builder = ::VagrantWindows::Provisioners::ChefCommandBuilder.new(
38
- @windows_machine, @config, :client)
39
-
40
- command_builder.prepare_for_chef_run()
41
- command = command_builder.run_chef_command()
37
+ command = ::VagrantWindows::Provisioners::ChefCommandBuilder.new(
38
+ @windows_machine, @config, :client).run_chef_command()
42
39
  ###################### END - monkey patched code ####################
43
40
 
44
41
  @config.attempts.times do |attempt|
@@ -32,11 +32,8 @@ module VagrantPlugins
32
32
  def run_chef_solo_on_windows
33
33
 
34
34
  #################### START - monkey patched code ####################
35
- command_builder = ::VagrantWindows::Provisioners::ChefCommandBuilder.new(
36
- @windows_machine, @config, :solo)
37
-
38
- command_builder.prepare_for_chef_run()
39
- command = command_builder.run_chef_command()
35
+ command = ::VagrantWindows::Provisioners::ChefCommandBuilder.new(
36
+ @windows_machine, @config, :solo).run_chef_command()
40
37
  ###################### END - monkey patched code ####################
41
38
 
42
39
  @config.attempts.times do |attempt|
@@ -34,12 +34,19 @@ module VagrantPlugins
34
34
  end
35
35
  comm.upload(path.to_s, fixed_upload_path)
36
36
 
37
- command = <<-EOH
38
- $old = Get-ExecutionPolicy;
39
- Set-ExecutionPolicy Unrestricted -force;
40
- #{win_friendly_path(fixed_upload_path)}#{args};
41
- Set-ExecutionPolicy $old -force
42
- EOH
37
+ # if powershell script we need to bypass the execution policy
38
+ command = "#{win_friendly_path(fixed_upload_path)}#{args}"
39
+ command = "powershell -executionpolicy bypass -file #{command}" if
40
+ File.extname(fixed_upload_path).downcase == '.ps1'
41
+
42
+ # for priviliged scripts we need wrap it in a scheduled task
43
+ if config.privileged
44
+ command = VagrantWindows.load_script_template('elevated_shell.ps1', :options => {
45
+ :command => command,
46
+ :username => windows_machine.winrm_config.username,
47
+ :password => windows_machine.winrm_config.password
48
+ })
49
+ end
43
50
 
44
51
  # Execute it with sudo
45
52
  comm.sudo(command) do |type, data|
@@ -22,58 +22,16 @@ module VagrantWindows
22
22
  @client_type = client_type
23
23
  end
24
24
 
25
- def prepare_for_chef_run()
26
- options = create_chef_options()
27
-
28
- # create cheftaskrun.ps1 that the scheduled task will invoke when run
29
- render_file_and_upload('cheftaskrun.ps1', options[:chef_task_run_ps1],
30
- :options => options)
31
-
32
- # create cheftask.xml that the scheduled task will be created with
33
- render_file_and_upload('cheftask.xml', options[:chef_task_xml],
34
- :options => options)
35
-
36
- # create cheftask.ps1 that will immediately invoke the scheduled task and wait for completion
37
- render_file_and_upload('cheftask.ps1', options[:chef_task_ps1],
38
- :options => options)
39
- end
40
-
41
25
  def run_chef_command()
42
- return <<-EOH
43
- $old = Get-ExecutionPolicy;
44
- Set-ExecutionPolicy Unrestricted -force;
45
- #{chef_task_ps1_path};
46
- Set-ExecutionPolicy $old -force
47
- EOH
48
- end
49
-
50
-
51
-
52
- def render_file_and_upload(script_name, dest_file, options)
53
- # render the script file to a local temp file and then upload
54
- script_local = Tempfile.new(script_name)
55
- IO.write(script_local, VagrantWindows.load_script_template(script_name, options))
56
- @windows_machine.winrmshell.upload(script_local, dest_file)
57
- end
58
-
59
- def create_chef_options
60
- command_env = @config.binary_env ? "#{@config.binary_env} " : ''
61
- return {
62
- :user => @windows_machine.winrm_config.username,
63
- :pass => @windows_machine.winrm_config.password,
64
- :chef_arguments => create_chef_arguments(),
65
- :chef_task_xml => provisioning_path('cheftask.xml'),
66
- :chef_task_running => provisioning_path('cheftask.running'),
67
- :chef_task_exitcode => provisioning_path('cheftask.exitcode'),
68
- :chef_task_ps1 => chef_task_ps1_path(),
69
- :chef_task_run_ps1 => provisioning_path('cheftaskrun.ps1'),
70
- :chef_stdout_log => provisioning_path("chef-#{@client_type}.log"),
71
- :chef_stderr_log => provisioning_path("chef-#{@client_type}.err.log"),
72
- :chef_binary_path => win_friendly_path("#{command_env}#{chef_binary_path}")
26
+ options = {
27
+ :command => "#{chef_binary_path} #{chef_arguments}",
28
+ :username => @windows_machine.winrm_config.username,
29
+ :password => @windows_machine.winrm_config.password
73
30
  }
31
+ return VagrantWindows.load_script_template('elevated_shell.ps1', :options => options)
74
32
  end
75
33
 
76
- def create_chef_arguments()
34
+ def chef_arguments()
77
35
  command_args = @config.arguments ? @config.arguments : ''
78
36
  chef_path = provisioning_path("#{@client_type}.rb")
79
37
  chef_dna_path = provisioning_path('dna.json')
@@ -84,10 +42,6 @@ module VagrantWindows
84
42
  chef_arguments.strip
85
43
  end
86
44
 
87
- def chef_task_ps1_path()
88
- provisioning_path('cheftask.ps1')
89
- end
90
-
91
45
  # Returns the path to the Chef binary, taking into account the
92
46
  # `binary_path` configuration option.
93
47
  def chef_binary_path()
@@ -102,4 +56,4 @@ module VagrantWindows
102
56
 
103
57
  end
104
58
  end
105
- end
59
+ end
@@ -0,0 +1,95 @@
1
+ $command = "<%= options[:command] %>"
2
+ $user = "<%= options[:username] %>"
3
+ $password = "<%= options[:password] %>"
4
+
5
+ $task_name = "WinRM_Elevated_Shell"
6
+ $out_file = "$env:SystemRoot\Temp\WinRM_Elevated_Shell.log"
7
+
8
+ if (Test-Path $out_file) {
9
+ del $out_file
10
+ }
11
+
12
+ $task_xml = @'
13
+ <?xml version="1.0" encoding="UTF-16"?>
14
+ <Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
15
+ <Principals>
16
+ <Principal id="Author">
17
+ <UserId>{user}</UserId>
18
+ <LogonType>Password</LogonType>
19
+ <RunLevel>HighestAvailable</RunLevel>
20
+ </Principal>
21
+ </Principals>
22
+ <Settings>
23
+ <MultipleInstancesPolicy>IgnoreNew</MultipleInstancesPolicy>
24
+ <DisallowStartIfOnBatteries>false</DisallowStartIfOnBatteries>
25
+ <StopIfGoingOnBatteries>false</StopIfGoingOnBatteries>
26
+ <AllowHardTerminate>true</AllowHardTerminate>
27
+ <StartWhenAvailable>false</StartWhenAvailable>
28
+ <RunOnlyIfNetworkAvailable>false</RunOnlyIfNetworkAvailable>
29
+ <IdleSettings>
30
+ <StopOnIdleEnd>true</StopOnIdleEnd>
31
+ <RestartOnIdle>false</RestartOnIdle>
32
+ </IdleSettings>
33
+ <AllowStartOnDemand>true</AllowStartOnDemand>
34
+ <Enabled>true</Enabled>
35
+ <Hidden>false</Hidden>
36
+ <RunOnlyIfIdle>false</RunOnlyIfIdle>
37
+ <WakeToRun>false</WakeToRun>
38
+ <ExecutionTimeLimit>PT2H</ExecutionTimeLimit>
39
+ <Priority>4</Priority>
40
+ </Settings>
41
+ <Actions Context="Author">
42
+ <Exec>
43
+ <Command>cmd</Command>
44
+ <Arguments>{arguments}</Arguments>
45
+ </Exec>
46
+ </Actions>
47
+ </Task>
48
+ '@
49
+
50
+ $bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
51
+ $encoded_command = [Convert]::ToBase64String($bytes)
52
+ $arguments = "/c powershell.exe -EncodedCommand $encoded_command &gt; $out_file 2&gt;&amp;1"
53
+
54
+ $task_xml = $task_xml.Replace("{arguments}", $arguments)
55
+ $task_xml = $task_xml.Replace("{user}", $user)
56
+
57
+ $schedule = New-Object -ComObject "Schedule.Service"
58
+ $schedule.Connect()
59
+ $task = $schedule.NewTask($null)
60
+ $task.XmlText = $task_xml
61
+ $folder = $schedule.GetFolder("\")
62
+ $folder.RegisterTaskDefinition($task_name, $task, 6, $user, $password, 1, $null) | Out-Null
63
+
64
+ $registered_task = $folder.GetTask("\$task_name")
65
+ $registered_task.Run($null) | Out-Null
66
+
67
+ $timeout = 10
68
+ $sec = 0
69
+ while ( (!($registered_task.state -eq 4)) -and ($sec -lt $timeout) ) {
70
+ Start-Sleep -s 1
71
+ $sec++
72
+ }
73
+
74
+ # Read the entire file, but only write out new lines we haven't seen before
75
+ $numLinesRead = 0
76
+ do {
77
+ Start-Sleep -m 100
78
+
79
+ if (Test-Path $out_file) {
80
+ $text = (get-content $out_file)
81
+ $numLines = ($text | Measure-Object -line).lines
82
+ $numLinesToRead = $numLines - $numLinesRead
83
+
84
+ if ($numLinesToRead -gt 0) {
85
+ $text | select -first $numLinesToRead -skip $numLinesRead | ForEach {
86
+ Write-Host "$_"
87
+ }
88
+ $numLinesRead += $numLinesToRead
89
+ }
90
+ }
91
+ } while (!($registered_task.state -eq 3))
92
+
93
+ $exit_code = $registered_task.LastTaskResult
94
+ [System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null
95
+ exit $exit_code
@@ -1,3 +1,3 @@
1
1
  module VagrantWindows
2
- VERSION = "1.6.0"
2
+ VERSION = "1.7.0.pre.2"
3
3
  end
data/locales/en.yml CHANGED
@@ -24,3 +24,10 @@ en:
24
24
  Password: %{password}
25
25
  Endpoint: %{endpoint}
26
26
  Message: %{message}
27
+
28
+ winrm_file_transfer_error: |-
29
+ Failed to transfer a file between the host and guest
30
+
31
+ From: %{from}
32
+ To: %{to}
33
+ Message: %{message}
@@ -32,70 +32,24 @@ describe VagrantWindows::Provisioners::ChefCommandBuilder, :unit => true do
32
32
  end
33
33
  end
34
34
 
35
- describe 'create_chef_arguments' do
35
+ describe 'chef_arguments' do
36
36
  it 'should include paths to client.rb and dna.json' do
37
37
  expected = '-c c:\tmp\vagrant-chef-1\client.rb -j c:\tmp\vagrant-chef-1\dna.json'
38
- @chef_cmd_builder.create_chef_arguments().should eql expected
38
+ @chef_cmd_builder.chef_arguments().should eql expected
39
39
  end
40
40
 
41
41
  it 'should include Chef arguments if specified' do
42
42
  @chef_config.stubs(:arguments).returns('-l DEBUG')
43
43
  expected = '-c c:\tmp\vagrant-chef-1\client.rb -j c:\tmp\vagrant-chef-1\dna.json -l DEBUG'
44
- @chef_cmd_builder.create_chef_arguments().should eql expected
44
+ @chef_cmd_builder.chef_arguments().should eql expected
45
45
  end
46
46
  end
47
47
 
48
- describe 'create_chef_options' do
49
- it "should include winrm username and password" do
50
- options = @chef_cmd_builder.create_chef_options()
51
- options[:user].should eql 'vagrant'
52
- options[:pass].should eql 'secret'
48
+ describe 'run chef command' do
49
+ it "should include chef-client cmd line" do
50
+ expect(@chef_cmd_builder.run_chef_command()).to include(
51
+ 'chef-client -c c:\\tmp\\vagrant-chef-1\\client.rb -j c:\\tmp\\vagrant-chef-1\\dna.json')
53
52
  end
54
-
55
- it 'should include paths to scripts' do
56
- options = @chef_cmd_builder.create_chef_options()
57
- options[:chef_task_xml].should eql 'c:\tmp\vagrant-chef-1\cheftask.xml'
58
- options[:chef_task_ps1].should eql 'c:\tmp\vagrant-chef-1\cheftask.ps1'
59
- options[:chef_task_run_ps1].should eql 'c:\tmp\vagrant-chef-1\cheftaskrun.ps1'
60
- end
61
-
62
- it 'should include paths to process flow files' do
63
- options = @chef_cmd_builder.create_chef_options()
64
- options[:chef_task_running].should eql 'c:\tmp\vagrant-chef-1\cheftask.running'
65
- options[:chef_task_exitcode].should eql 'c:\tmp\vagrant-chef-1\cheftask.exitcode'
66
- end
67
-
68
- it 'should include paths to logs' do
69
- options = @chef_cmd_builder.create_chef_options()
70
- options[:chef_stdout_log].should eql 'c:\tmp\vagrant-chef-1\chef-client.log'
71
- options[:chef_stderr_log].should eql 'c:\tmp\vagrant-chef-1\chef-client.err.log'
72
- end
73
-
74
- it 'should include path to chef binary' do
75
- options = @chef_cmd_builder.create_chef_options()
76
- options[:chef_binary_path].should eql 'chef-client'
77
- end
78
-
79
- it 'should include full path to chef binary when binary_path is set' do
80
- @chef_config.stubs(:binary_path).returns('c:/opscode/chef/bin')
81
- options = @chef_cmd_builder.create_chef_options()
82
- options[:chef_binary_path].should eql 'c:\opscode\chef\bin\chef-client'
83
- end
84
-
85
- end
86
-
87
- describe 'prepare_for_chef_run' do
88
- it 'should upload cheftask scripts' do
89
- winrmshell = double()
90
- @windows_machine.stubs(:winrmshell).returns(winrmshell)
91
-
92
- winrmshell.should_receive(:upload).with(anything(), 'c:\tmp\vagrant-chef-1\cheftaskrun.ps1')
93
- winrmshell.should_receive(:upload).with(anything(), 'c:\tmp\vagrant-chef-1\cheftask.xml')
94
- winrmshell.should_receive(:upload).with(anything(), 'c:\tmp\vagrant-chef-1\cheftask.ps1')
95
-
96
- @chef_cmd_builder.prepare_for_chef_run()
97
- end
98
-
99
53
  end
100
54
 
101
55
  end
@@ -2,11 +2,16 @@ require 'spec_helper'
2
2
 
3
3
  describe VagrantWindows::Communication::GuestNetwork , :integration => true do
4
4
 
5
- before(:all) do
6
- # This test requires you already have a running Windows Server 2008 R2 Vagrant VM
7
- # Not ideal, but you have to start somewhere
8
- @shell = VagrantWindows::Communication::WinRMShell.new("127.0.0.1", "vagrant", "vagrant")
9
- @guestnetwork = VagrantWindows::Communication::GuestNetwork.new(@shell)
5
+ before(:each) do
6
+ port = (ENV['WINRM_PORT'] || 5985).to_i
7
+
8
+ @machine = stub()
9
+ @shell = VagrantWindows::Communication::WinRMShell.new(
10
+ "127.0.0.1", "vagrant", "vagrant", { port: port })
11
+
12
+ @communicator = VagrantWindows::Communication::WinRMCommunicator.new(@machine)
13
+ @communicator.winrmshell = @shell
14
+ @guestnetwork = VagrantWindows::Communication::GuestNetwork.new(@communicator)
10
15
  end
11
16
 
12
17
  describe "wsman_version" do
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+ require 'vagrant-windows/communication/linux_command_filter'
3
+
4
+ describe VagrantWindows::Communication::LinuxCommandFilter, :unit => true do
5
+
6
+ before(:each) do
7
+ @cmd_filter = VagrantWindows::Communication::LinuxCommandFilter.new()
8
+ end
9
+
10
+ describe 'command filters' do
11
+ it 'should initialize all command filters in command filters directory' do
12
+ expect(@cmd_filter.command_filters()).not_to be_empty
13
+ end
14
+ end
15
+
16
+ describe 'filter' do
17
+ it 'should filter out uname commands' do
18
+ expect(@cmd_filter.filter('uname -s stuff')).to eq('')
19
+ end
20
+
21
+ it 'should filter out which commands' do
22
+ expect(@cmd_filter.filter('which ruby')).to include(
23
+ '[Array](Get-Command ruby -errorAction SilentlyContinue)')
24
+ end
25
+
26
+ it 'should filter out test -d commands' do
27
+ expect(@cmd_filter.filter('test -d /tmp/dir')).to eq(
28
+ "if ((Test-Path '/tmp/dir') -and (get-item '/tmp/dir').PSIsContainer) { exit 0 } exit 1")
29
+ end
30
+
31
+ it 'should filter out test -f commands' do
32
+ expect(@cmd_filter.filter('test -f /tmp/file.txt')).to eq(
33
+ "if ((Test-Path '/tmp/file.txt') -and (!(get-item '/tmp/file.txt').PSIsContainer)) { exit 0 } exit 1")
34
+ end
35
+
36
+ it 'should filter out test -x commands' do
37
+ expect(@cmd_filter.filter('test -x /tmp/file.txt')).to eq(
38
+ "if ((Test-Path '/tmp/file.txt') -and (!(get-item '/tmp/file.txt').PSIsContainer)) { exit 0 } exit 1")
39
+ end
40
+
41
+ it 'should filter out other test commands' do
42
+ expect(@cmd_filter.filter('test -L /tmp/file.txt')).to eq(
43
+ "if (Test-Path '/tmp/file.txt') { exit 0 } exit 1")
44
+ end
45
+
46
+ it 'should filter out rm -Rf commands' do
47
+ expect(@cmd_filter.filter('rm -Rf /some/dir')).to eq(
48
+ "rm '/some/dir' -recurse -force")
49
+ end
50
+
51
+ it 'should filter out rm commands' do
52
+ expect(@cmd_filter.filter('rm /some/dir')).to eq(
53
+ "rm '/some/dir' -force")
54
+ end
55
+
56
+ it 'should filter out chown commands' do
57
+ expect(@cmd_filter.filter("chown -R root '/tmp/dir'")).to eq('')
58
+ end
59
+
60
+ it 'should filter out chmod commands' do
61
+ expect(@cmd_filter.filter("chmod 0600 ~/.ssh/authorized_keys")).to eq('')
62
+ end
63
+
64
+ it 'should filter out certain cat commands' do
65
+ expect(@cmd_filter.filter("cat /etc/release | grep -i OmniOS")).to eq('')
66
+ end
67
+
68
+ it 'should not filter out other cat commands' do
69
+ expect(@cmd_filter.filter("cat /tmp/somefile")).to eq('cat /tmp/somefile')
70
+ end
71
+ end
72
+
73
+ end
@@ -3,10 +3,10 @@ require 'spec_helper'
3
3
  describe VagrantWindows::Communication::WinRMCommunicator, :integration => true do
4
4
 
5
5
  before(:all) do
6
- # This test requires you already have a running Windows Server 2008 R2 Vagrant VM
7
- # Not ideal, but you have to start somewhere
8
6
  @communicator = VagrantWindows::Communication::WinRMCommunicator.new({})
9
- @communicator.winrmshell = VagrantWindows::Communication::WinRMShell.new("127.0.0.1", "vagrant", "vagrant")
7
+ port = (ENV['WINRM_PORT'] || 5985).to_i
8
+ @communicator.winrmshell = VagrantWindows::Communication::WinRMShell.new(
9
+ "127.0.0.1", "vagrant", "vagrant", { port: port })
10
10
  end
11
11
 
12
12
  describe "execute" do
@@ -28,20 +28,69 @@ describe VagrantWindows::Communication::WinRMCommunicator, :integration => true
28
28
  it "should upload the file and overwrite it if it exists" do
29
29
  test_file = Tempfile.new("uploadtest")
30
30
  IO.write(test_file, "hello world")
31
- @communicator.upload(test_file, "c:\\vagrantuploadtest.txt")
31
+ @communicator.upload(test_file, "c:/tmp/winrm-test/vagrantuploadtest.txt")
32
32
 
33
33
  # ensure we can overwrite
34
34
  IO.write(test_file, "goodbye cruel world")
35
- @communicator.upload(test_file, "c:\\vagrantuploadtest.txt")
35
+ @communicator.upload(test_file, "c:/tmp/winrm-test/vagrantuploadtest.txt")
36
36
 
37
37
  # get the uploaded file's contents to ensure it uploaded properly
38
38
  uploaded_file_content = ''
39
- @communicator.execute("cat c:\\vagrantuploadtest.txt", {}) do |type, line|
39
+ @communicator.execute("cat c:/tmp/winrm-test/vagrantuploadtest.txt", {}) do |type, line|
40
40
  uploaded_file_content = uploaded_file_content + line
41
41
  end
42
42
 
43
43
  expect(uploaded_file_content.chomp).to eq("goodbye cruel world")
44
44
  end
45
+
46
+ it "should recursively upload directories" do
47
+ # create a some test data
48
+ host_src_dir = Dir.mktmpdir("winrm_comm")
49
+
50
+ begin
51
+ IO.write(File.join(host_src_dir, 'root.txt'), "root\n")
52
+
53
+ subdir2 = File.join(host_src_dir, '/subdir1/subdir2')
54
+ FileUtils.mkdir_p(subdir2)
55
+
56
+ IO.write(File.join(subdir2, 'leaf1.txt'), "leaf1\n")
57
+ IO.write(File.join(subdir2, 'leaf2.txt'), "leaf2\n")
58
+
59
+ @communicator.upload(host_src_dir, '/tmp/winrm-test-upload') #c:\tmp\winrm-test-upload
60
+
61
+ @communicator.execute <<-EOH
62
+ function AssertExists($p) {
63
+ if (!(Test-Path $p)) {
64
+ exit 1
65
+ }
66
+ }
67
+
68
+ AssertExists 'c:/tmp/winrm-test-upload/root.txt'
69
+ AssertExists 'c:/tmp/winrm-test-upload/subdir1/subdir2/leaf2.txt'
70
+ AssertExists 'c:/tmp/winrm-test-upload/subdir1/subdir2/leaf1.txt'
71
+ EOH
72
+ ensure
73
+ FileUtils.remove_entry_secure host_src_dir
74
+ end
75
+ end
76
+ end
77
+
78
+ describe 'test' do
79
+ it "should return true if directory exists" do
80
+ @communicator.execute('mkdir -p /tmp/winrm-test/1')
81
+ expect(@communicator.test('test -d /tmp/winrm-test/1')).to be_true
82
+ end
83
+
84
+ it "should return false if directory does not exist" do
85
+ expect(@communicator.test('test -d /tmp/winrm-test/doesnotexit')).to be_false
86
+ end
87
+
88
+ it "should differentiate between directories and files" do
89
+ @communicator.execute('mkdir -p /tmp/winrm-test/2')
90
+ @communicator.execute('Add-Content /tmp/winrm-test/2/file.txt "The content"')
91
+ expect(@communicator.test('test -d /tmp/winrm-test/2/file.txt')).to be_false
92
+ expect(@communicator.test('test -f /tmp/winrm-test/2/file.txt')).to be_true
93
+ end
45
94
  end
46
95
 
47
96
  end