Added WinRM command filters
These will be used to replace the guest side command_alias script that is sent with every communicator execute call. This avoids some uncessary remote calls to the guest, makes it unit testable, and allows larger PowerShell commands to be invoked.
This commit is contained in:
parent
fdb6461af4
commit
96ab8f60c5
|
@ -0,0 +1,47 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module CommunicatorWinRM
|
||||||
|
|
||||||
|
# Handles loading and applying all available WinRM command filters
|
||||||
|
class CommandFilter
|
||||||
|
|
||||||
|
@@cmd_filters = [
|
||||||
|
"cat",
|
||||||
|
"chmod",
|
||||||
|
"chown",
|
||||||
|
"rm",
|
||||||
|
"test",
|
||||||
|
"uname",
|
||||||
|
"which"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Filter the given Vagrant command to ensure compatibility with Windows
|
||||||
|
#
|
||||||
|
# @param [String] The Vagrant shell command
|
||||||
|
# @returns [String] Windows runnable command or empty string
|
||||||
|
def filter(command)
|
||||||
|
command_filters.each { |c| command = c.filter(command) if c.accept?(command) }
|
||||||
|
command
|
||||||
|
end
|
||||||
|
|
||||||
|
# All the available Linux command filters
|
||||||
|
#
|
||||||
|
# @returns [Array] All Linux command filter instances
|
||||||
|
def command_filters
|
||||||
|
@command_filters ||= create_command_filters()
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_command_filters
|
||||||
|
[].tap do |filters|
|
||||||
|
@@cmd_filters.each do |cmd|
|
||||||
|
require_relative "command_filters/#{cmd}"
|
||||||
|
class_name = "VagrantPlugins::CommunicatorWinRM::CommandFilters::#{cmd.capitalize}"
|
||||||
|
filters << Module.const_get(class_name).new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,27 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module CommunicatorWinRM
|
||||||
|
module CommandFilters
|
||||||
|
|
||||||
|
# Handles the special case of determining the guest OS using cat
|
||||||
|
class Cat
|
||||||
|
|
||||||
|
def filter(command)
|
||||||
|
# cat /etc/release | grep -i OmniOS
|
||||||
|
# cat /etc/redhat-release
|
||||||
|
# cat /etc/issue | grep 'Core Linux'
|
||||||
|
# cat /etc/release | grep -i SmartOS
|
||||||
|
''
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept?(command)
|
||||||
|
# cat works in PowerShell, however we don't want to run Guest
|
||||||
|
# OS detection as this will fail on Windows because the lack of the
|
||||||
|
# grep command
|
||||||
|
command.start_with?('cat /etc/')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,21 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module CommunicatorWinRM
|
||||||
|
module CommandFilters
|
||||||
|
|
||||||
|
# Converts a *nix 'chmod' command to a PowerShell equivalent
|
||||||
|
class Chmod
|
||||||
|
|
||||||
|
def filter(command)
|
||||||
|
# Not support on Windows, the communicator will skip this command
|
||||||
|
''
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept?(command)
|
||||||
|
command.start_with?('chmod ')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,21 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module CommunicatorWinRM
|
||||||
|
module CommandFilters
|
||||||
|
|
||||||
|
# Converts a *nix 'chown' command to a PowerShell equivalent
|
||||||
|
class Chown
|
||||||
|
|
||||||
|
def filter(command)
|
||||||
|
# Not support on Windows, the communicator will skip this command
|
||||||
|
''
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept?(command)
|
||||||
|
command.start_with?('chown ')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,28 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module CommunicatorWinRM
|
||||||
|
module CommandFilters
|
||||||
|
|
||||||
|
# Converts a *nix 'rm' command to a PowerShell equivalent
|
||||||
|
class Rm
|
||||||
|
|
||||||
|
def filter(command)
|
||||||
|
# rm -Rf /some/dir
|
||||||
|
# rm /some/dir
|
||||||
|
cmd_parts = command.strip.split(/\s+/)
|
||||||
|
dir = cmd_parts[1]
|
||||||
|
if dir == '-Rf'
|
||||||
|
dir = cmd_parts[2]
|
||||||
|
return "rm '#{dir}' -recurse -force"
|
||||||
|
end
|
||||||
|
return "rm '#{dir}' -force"
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept?(command)
|
||||||
|
command.start_with?('rm ')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,37 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module CommunicatorWinRM
|
||||||
|
module CommandFilters
|
||||||
|
|
||||||
|
# Converts a *nix 'test' command to a PowerShell equivalent
|
||||||
|
class Test
|
||||||
|
|
||||||
|
def filter(command)
|
||||||
|
# test -d /tmp/dir
|
||||||
|
# test -f /tmp/afile
|
||||||
|
# test -L /somelink
|
||||||
|
# test -x /tmp/some.exe
|
||||||
|
|
||||||
|
cmd_parts = command.strip.split(/\s+/)
|
||||||
|
if cmd_parts[1] == '-d'
|
||||||
|
# ensure it exists and is a directory
|
||||||
|
return "if ((Test-Path '#{cmd_parts[2]}') -and (get-item '#{cmd_parts[2]}').PSIsContainer) { exit 0 } exit 1"
|
||||||
|
elsif cmd_parts[1] == '-f' || cmd_parts[1] == '-x'
|
||||||
|
# ensure it exists and is a file
|
||||||
|
return "if ((Test-Path '#{cmd_parts[2]}') -and (!(get-item '#{cmd_parts[2]}').PSIsContainer)) { exit 0 } exit 1"
|
||||||
|
end
|
||||||
|
|
||||||
|
# otherwise, just check for existence
|
||||||
|
return "if (Test-Path '#{cmd_parts[2]}') { exit 0 } exit 1"
|
||||||
|
end
|
||||||
|
|
||||||
|
# if (Test-Path 'c:\windows' && (get-item 'c:\windows').PSIsContainer) { Write-Host 0 } Write-Host 1
|
||||||
|
|
||||||
|
def accept?(command)
|
||||||
|
command.start_with?('test ')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,31 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module CommunicatorWinRM
|
||||||
|
module CommandFilters
|
||||||
|
|
||||||
|
# Converts a *nix 'uname' command to a PowerShell equivalent
|
||||||
|
class Uname
|
||||||
|
|
||||||
|
def filter(command)
|
||||||
|
# uname -s | grep 'Darwin'
|
||||||
|
# uname -s | grep VMkernel
|
||||||
|
# uname -s | grep 'FreeBSD'
|
||||||
|
# uname -s | grep 'Linux'
|
||||||
|
# uname -s | grep NetBSD
|
||||||
|
# uname -s | grep 'OpenBSD'
|
||||||
|
# uname -sr | grep SunOS | grep -v 5.11
|
||||||
|
# uname -sr | grep 'SunOS 5.11'
|
||||||
|
|
||||||
|
# uname is used to detect the guest type in Vagrant, so don't bother running
|
||||||
|
# to speed up OS detection
|
||||||
|
''
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept?(command)
|
||||||
|
command.start_with?('uname ')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,26 @@
|
||||||
|
module VagrantPlugins
|
||||||
|
module CommunicatorWinRM
|
||||||
|
module CommandFilters
|
||||||
|
|
||||||
|
# Converts a *nix 'which' command to a PowerShell equivalent
|
||||||
|
class Which
|
||||||
|
|
||||||
|
def filter(command)
|
||||||
|
executable = command.strip.split(/\s+/)[1]
|
||||||
|
return <<-EOH
|
||||||
|
$command = [Array](Get-Command #{executable} -errorAction SilentlyContinue)
|
||||||
|
if ($null -eq $command) { exit 1 }
|
||||||
|
write-host $command[0].Definition
|
||||||
|
exit 0
|
||||||
|
EOH
|
||||||
|
end
|
||||||
|
|
||||||
|
def accept?(command)
|
||||||
|
command.start_with?('which ')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,70 @@
|
||||||
|
require File.expand_path("../../../../base", __FILE__)
|
||||||
|
|
||||||
|
require Vagrant.source_root.join("plugins/communicators/winrm/command_filter")
|
||||||
|
|
||||||
|
describe VagrantPlugins::CommunicatorWinRM::CommandFilter, :unit => true do
|
||||||
|
|
||||||
|
describe '.command_filters' do
|
||||||
|
it 'initializes all command filters in command filters directory' do
|
||||||
|
expect(subject.command_filters()).not_to be_empty
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.filter' do
|
||||||
|
it 'filters out uname commands' do
|
||||||
|
expect(subject.filter('uname -s stuff')).to eq('')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'filters out which commands' do
|
||||||
|
expect(subject.filter('which ruby')).to include(
|
||||||
|
'[Array](Get-Command ruby -errorAction SilentlyContinue)')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'filters out test -d commands' do
|
||||||
|
expect(subject.filter('test -d /tmp/dir')).to eq(
|
||||||
|
"if ((Test-Path '/tmp/dir') -and (get-item '/tmp/dir').PSIsContainer) { exit 0 } exit 1")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'filters out test -f commands' do
|
||||||
|
expect(subject.filter('test -f /tmp/file.txt')).to eq(
|
||||||
|
"if ((Test-Path '/tmp/file.txt') -and (!(get-item '/tmp/file.txt').PSIsContainer)) { exit 0 } exit 1")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'filters out test -x commands' do
|
||||||
|
expect(subject.filter('test -x /tmp/file.txt')).to eq(
|
||||||
|
"if ((Test-Path '/tmp/file.txt') -and (!(get-item '/tmp/file.txt').PSIsContainer)) { exit 0 } exit 1")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'filters out other test commands' do
|
||||||
|
expect(subject.filter('test -L /tmp/file.txt')).to eq(
|
||||||
|
"if (Test-Path '/tmp/file.txt') { exit 0 } exit 1")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'filters out rm -Rf commands' do
|
||||||
|
expect(subject.filter('rm -Rf /some/dir')).to eq(
|
||||||
|
"rm '/some/dir' -recurse -force")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'filters out rm commands' do
|
||||||
|
expect(subject.filter('rm /some/dir')).to eq(
|
||||||
|
"rm '/some/dir' -force")
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'filters out chown commands' do
|
||||||
|
expect(subject.filter("chown -R root '/tmp/dir'")).to eq('')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'filters out chmod commands' do
|
||||||
|
expect(subject.filter("chmod 0600 ~/.ssh/authorized_keys")).to eq('')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'filters out certain cat commands' do
|
||||||
|
expect(subject.filter("cat /etc/release | grep -i OmniOS")).to eq('')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should not filter out other cat commands' do
|
||||||
|
expect(subject.filter("cat /tmp/somefile")).to eq('cat /tmp/somefile')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
Loading…
Reference in New Issue