Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(BOLT-608) Add `local` transport for Windows OS #775

Merged
merged 2 commits into from Dec 10, 2018
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Next

(BOLT-608) Add `local` transport for Windows OS

Add support for local transport on windows OS. The WinRM and Local transports now share some common powershell code generation functionality. The powershell templating has been pulled out into a `Powerhsell` module in order to share.
  • Loading branch information
donoghuc committed Nov 30, 2018
commit 0b5f454a5bc6c3d7218cae9b013bdda7734b4303
@@ -24,7 +24,7 @@ end

desc "Run RSpec tests for TravisCI that don't require WinRM"
RSpec::Core::RakeTask.new(:travisci) do |t|
t.rspec_opts = '--tag ~winrm --tag ~appveyor_agents --tag ~puppetserver'
t.rspec_opts = '--tag ~winrm --tag ~appveyor_agents --tag ~puppetserver --tag ~windows'
end

desc "Run RSpec tests that require pupperserver"
@@ -127,6 +127,11 @@ namespace :integration do
t.rspec_opts = '--tag bash'
end

desc 'Run tests that require windows OS on the local host'
RSpec::Core::RakeTask.new(:windows) do |t|
t.rspec_opts = '--tag windows'
end

desc 'Run tests that require Puppet Agents configured with Appveyor'
RSpec::Core::RakeTask.new(:appveyor_agents) do |t|
t.rspec_opts = '--tag appveyor_agents'
@@ -174,7 +174,7 @@ def update_target(target)
data['config'] = {}
end

unless Bolt::Util.windows? || data['config']['transport']
unless data['config']['transport']
data['config']['transport'] = 'local' if target.name == 'localhost'

This comment has been minimized.

Copy link
@MikaelSmith

MikaelSmith Dec 10, 2018

Member

Whole thing could be collapsed to data['config']['transport'] ||= 'local' if target.name == 'localhost'.

end

@@ -4,6 +4,7 @@
require 'fileutils'
require 'tmpdir'
require 'bolt/transport/base'
require 'bolt/transport/powershell'
require 'bolt/util'

module Bolt
@@ -21,12 +22,7 @@ def self.validate(_options); end

def initialize
super

if Bolt::Util.windows?
raise NotImplementedError, "The local transport is not yet implemented on Windows"
else
@conn = Shell.new
end
@conn = Shell.new
end

def in_tmpdir(base)
@@ -73,12 +69,24 @@ def run_script(target, script, arguments, _options = {})

# unpack any Sensitive data AFTER we log
arguments = unwrap_sensitive_args(arguments)
if arguments.empty?
# We will always provide separated arguments, so work-around Open3's handling of a single
# argument as the entire command string for script paths containing spaces.
arguments = ['']
if Bolt::Util.windows?
This conversation was marked as resolved by MikaelSmith

This comment has been minimized.

Copy link
@MikaelSmith

MikaelSmith Dec 6, 2018

Member

Seems promising.

if Powershell.powershell_file?(file)
command = Powershell.run_script(arguments, file)
output = @conn.execute(command, dir: dir, env: "powershell.exe")
else
path, args = *Powershell.process_from_extension(file)
args += Powershell.escape_arguments(arguments)
command = args.unshift(path).join(' ')
output = @conn.execute(command, dir: dir)
end
else
if arguments.empty?
# We will always provide separated arguments, so work-around Open3's handling of a single
# argument as the entire command string for script paths containing spaces.
arguments = ['']
end
output = @conn.execute(file, *arguments, dir: dir)
end
output = @conn.execute(file, *arguments, dir: dir)
Bolt::Result.for_command(target, output.stdout.string, output.stderr.string, output.exit_code)
end
end
@@ -88,6 +96,7 @@ def run_task(target, task, arguments, _options = {})
executable = implementation['path']
input_method = implementation['input_method']
extra_files = implementation['files']
input_method ||= Powershell.powershell_file?(executable) ? 'powershell' : 'both'

in_tmpdir(target.options['tmpdir']) do |dir|
if extra_files.empty?
@@ -108,16 +117,43 @@ def run_task(target, task, arguments, _options = {})
copy_file(executable, script)
File.chmod(0o750, script)

# unpack any Sensitive data, write it to a separate variable because
# we log 'arguments' below
# log the arguments with sensitive data redacted, do NOT log unwrapped_arguments
logger.debug("Running '#{script}' with #{arguments}")
unwrapped_arguments = unwrap_sensitive_args(arguments)

stdin = STDIN_METHODS.include?(input_method) ? JSON.dump(unwrapped_arguments) : nil
env = ENVIRONMENT_METHODS.include?(input_method) ? envify_params(unwrapped_arguments) : nil

# log the arguments with sensitive data redacted, do NOT log unwrapped_arguments
logger.debug("Running '#{script}' with #{arguments}")
if Bolt::Util.windows?
# WINDOWS
if ENVIRONMENT_METHODS.include?(input_method)
environment_params = envify_params(unwrapped_arguments).each_with_object([]) do |(arg, val), list|
list << Powershell.set_env(arg, val)
end
environment_params = environment_params.join("\n") + "\n"
else
environment_params = ""
end

output = @conn.execute(script, stdin: stdin, env: env, dir: dir)
output =
if Powershell.powershell_file?(script) && stdin.nil?
command = Powershell.run_ps_task(arguments, script, input_method)
command = environment_params + Powershell.shell_init + command
if input_method == 'powershell'
@conn.execute(command, dir: dir, env: "powershell.exe")
else
@conn.execute(command, dir: dir, stdin: stdin, env: "powershell.exe")

This comment has been minimized.

Copy link
@MikaelSmith

MikaelSmith Dec 10, 2018

Member

This feels like a weird use of env. env was supposed to be about setting up environment variables. However it looks like the way we order that in shell.rb doesn't work for Windows.

end
else
path, args = *Powershell.process_from_extension(script)
command = args.unshift(path).join(' ')
command = environment_params + Powershell.shell_init + command
@conn.execute(command, dir: dir, stdin: stdin, env: "powershell.exe")
end
else
# POSIX
env = ENVIRONMENT_METHODS.include?(input_method) ? envify_params(unwrapped_arguments) : nil
output = @conn.execute(script, stdin: stdin, env: env, dir: dir)
end
Bolt::Result.for_task(target, output.stdout.string, output.stderr.string, output.exit_code)
end
end
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.