From 85462ab074429c51ad792432632d67fce5768807 Mon Sep 17 00:00:00 2001 From: Akos Murati Date: Wed, 4 Feb 2015 18:08:35 +1300 Subject: [PATCH 1/9] Fixing Exit code issue for remote MD5 hash calculation --- lib/kitchen/transport/winrm.rb | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/kitchen/transport/winrm.rb b/lib/kitchen/transport/winrm.rb index 75c781fea..0c5910805 100644 --- a/lib/kitchen/transport/winrm.rb +++ b/lib/kitchen/transport/winrm.rb @@ -28,6 +28,7 @@ end require "logger" +require 'pry' require "kitchen/errors" require "kitchen/login_command" @@ -327,6 +328,7 @@ def upload_file(local, remote) end logger.debug("Finished '#{remote}' Thread: #{Thread.current}") end + #binding.pry end # Checks to see if the target file on the guest is missing or out of date. @@ -351,12 +353,18 @@ def should_upload_file?(local, remote) $file.Dispose() } if ($guest_md5 -eq '#{local_md5}') { - exit 0 + [Environment]::ExitCode = 0 + return 0 } } -exit 1 +[Environment]::ExitCode = 1 +return 1 EOH - powershell(command)[:exitcode] == 1 + result = powershell(command) + #should = (powershell(command)[:exitcode] == 1) + should = (result[:data][0][:stdout] == "1") + #binding.pry + should end # Uploads the given file to a new temp file on the guest @@ -410,6 +418,7 @@ def decode_temp_file(local, remote) [System.IO.File]::WriteAllBytes($dest_file_path, $bytes) EOH raise_upload_error_if_failed(output, local, remote) + ##binding.pry end # Creates a guest file path equivalent from a host file path From 452082a44ac96fd94530403122f2a40362a26ef3 Mon Sep 17 00:00:00 2001 From: Akos Murati Date: Tue, 10 Feb 2015 13:30:34 +1300 Subject: [PATCH 2/9] Created a separated file-transfer for busser to support WinRM for larger files, instead of using raw echo commands. --- lib/kitchen/busser.rb | 55 ++++++++++++++++++++++++++++++++++++-- lib/kitchen/driver/base.rb | 12 ++++++++- 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/lib/kitchen/busser.rb b/lib/kitchen/busser.rb index 34d3bf98c..ae5c4c231 100644 --- a/lib/kitchen/busser.rb +++ b/lib/kitchen/busser.rb @@ -56,6 +56,8 @@ def initialize(suite_name, opts = {}) @config[:root_path] = opts.fetch(:root_path, DEFAULT_ROOT_PATH) @config[:version] = opts.fetch(:version, "busser") @config[:busser_bin] = opts.fetch(:busser_bin, File.join(@config[:root_path], "bin/busser")) + @config[:remote_transfer_path] = File.join(config[:root_path],'transfer') + @config[:local_transfer_path] = nil end # Returns the name of this busser, suitable for display in a CLI. @@ -89,6 +91,50 @@ def diagnose result end + # Clears local and constructs a remote command to clean-up busser transfer directory + # + # @return [string] a shell transfer specific directory delete command + def cleanup_cmd + #Empty the previous local transfer folder + FileUtils.rm_rf(config[:local_transfer_path]) if config[:local_transfer_path] + + case shell + when "bourne" + cmd = <<-CMD.gsub(/^ {10}/, "") + rmdir -rf #{config[:remote_transfer_path]} + CMD + when "powershell" + cmd = <<-CMD.gsub(/^ {10}/, "") + rmdir -Recurse -Force -ea 0 #{config[:remote_transfer_path]} | out-null + exit 0 + CMD + else + raise "[#{self}] Unsupported shell: #{shell}" + end + Util.wrap_command(cmd, shell) + end + + # Prepare function to prepare busser test files for a transfer + # + # @return [Hash] a hash list of local transfer files with its remote target directory + def sync_files + # Initialize a new transfer folder + config[:local_transfer_path] = Dir.mktmpdir("#{instance.name}-busser-transfer") + + fileList=Array.new + local_suite_files.each do |f| + raw_content = IO.read(f) + md5 = Digest::MD5.hexdigest(raw_content) + remote_dir = config[:remote_transfer_path] + temp_file = File.join(config[:local_transfer_path],md5) + encoded_content = Base64.encode64(raw_content).gsub("\n", "") + IO.binwrite(temp_file,encoded_content) + + fileList.push({local: temp_file , remote: remote_dir}) + end + fileList + end + # Returns a command string which installs Busser, and installs all # required Busser plugins for the suite. # @@ -204,6 +250,8 @@ def finalize_config!(instance) DEFAULT_RUBY_BINDIR = "/opt/chef/embedded/bin".freeze DEFAULT_ROOT_PATH = "/tmp/busser".freeze + BUSSER_TRANSFER_PATH = nil + # Loads any needed dependencies # # @raise [ClientError] if any library loading fails or any of the @@ -312,8 +360,11 @@ def remote_file(file, dir) # @api private def stream_file(local_path, remote_path) local_file = IO.read(local_path) - encoded_file = Base64.encode64(local_file).gsub("\n", "") + + #encoded_file = Base64.encode64(local_file).gsub("\n", "") md5 = Digest::MD5.hexdigest(local_file) + transfer_path = File.join(File.join(config[:root_path],'transfer'),md5) + perms = format("%o", File.stat(local_path).mode)[2, 4] stream_cmd = [ sudo(config[:busser_bin]), @@ -325,7 +376,7 @@ def stream_file(local_path, remote_path) [ %{echo "Uploading #{remote_path} (mode=#{perms})"}, - %{echo "#{encoded_file}" | #{stream_cmd}} + %{cat "#{transfer_path}" | #{stream_cmd}} ].join("\n").concat("\n") end diff --git a/lib/kitchen/driver/base.rb b/lib/kitchen/driver/base.rb index a59d8245d..802b4f690 100644 --- a/lib/kitchen/driver/base.rb +++ b/lib/kitchen/driver/base.rb @@ -20,6 +20,7 @@ require "kitchen/lazy_hash" + module Kitchen module Driver @@ -86,14 +87,23 @@ def setup(state) end end - # Verifies a converged instance. + # Uploads latest test files and verifies a converged instance. # # @param state [Hash] mutable instance and driver state # @raise [ActionFailed] if the action could not be completed def verify(state) transport.connection(state) do |conn| + + conn.execute(busser.cleanup_cmd) + + busser.sync_files.each do |file| + conn.upload!(file[:local], file[:remote]) + end + conn.execute(busser.sync_cmd) conn.execute(busser.run_cmd) + + conn.execute(busser.cleanup_cmd) end end From 3e406b137f02cd6a8669d96db3c30bd690ea12e4 Mon Sep 17 00:00:00 2001 From: Akos Murati Date: Tue, 10 Feb 2015 17:53:44 +1300 Subject: [PATCH 3/9] Set-ExecutionPolicy to enable Pester on Server 2008 --- lib/kitchen/busser.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/kitchen/busser.rb b/lib/kitchen/busser.rb index ae5c4c231..b20e005a5 100644 --- a/lib/kitchen/busser.rb +++ b/lib/kitchen/busser.rb @@ -414,6 +414,7 @@ def busser_setup_env ].join(" ") when "powershell" [ + %{Set-ExecutionPolicy RemoteSigned}, %{$env:BUSSER_ROOT="#{config[:root_path]}";}, %{$env:PATH="$env:PATH;/opscode/chef/embedded/bin";}, %{try { $env:BUSSER_SUITE_PATH=@(#{@config[:busser_bin]} suite path) }}, From 45576c8c58b98e67728ecef0172701533cfcfdd2 Mon Sep 17 00:00:00 2001 From: Akos Murati Date: Wed, 11 Feb 2015 09:14:42 +1300 Subject: [PATCH 4/9] Adds Busser cleanup for Windows --- lib/kitchen/busser.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/kitchen/busser.rb b/lib/kitchen/busser.rb index b20e005a5..564490976 100644 --- a/lib/kitchen/busser.rb +++ b/lib/kitchen/busser.rb @@ -165,7 +165,10 @@ def setup_cmd when "powershell" cmd = <<-CMD.gsub(/^ {10}/, "") #{busser_setup_env} + echo 'Cleaning up busser...' + gem uninstall #{plugins.join(" ")} + echo 'Setting up busser...' if ((gem list busser -i) -eq \"false\") { gem install #{gem_install_args} } @@ -414,7 +417,6 @@ def busser_setup_env ].join(" ") when "powershell" [ - %{Set-ExecutionPolicy RemoteSigned}, %{$env:BUSSER_ROOT="#{config[:root_path]}";}, %{$env:PATH="$env:PATH;/opscode/chef/embedded/bin";}, %{try { $env:BUSSER_SUITE_PATH=@(#{@config[:busser_bin]} suite path) }}, From 3fb59e9efecd7c5805805a48647af23c8d475b3a Mon Sep 17 00:00:00 2001 From: Akos Murati Date: Fri, 13 Feb 2015 02:41:57 +1300 Subject: [PATCH 5/9] Commenting code --- lib/kitchen/busser.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/kitchen/busser.rb b/lib/kitchen/busser.rb index 564490976..13b6bf65c 100644 --- a/lib/kitchen/busser.rb +++ b/lib/kitchen/busser.rb @@ -114,7 +114,7 @@ def cleanup_cmd Util.wrap_command(cmd, shell) end - # Prepare function to prepare busser test files for a transfer + # Prepare busser test files to be transferred to the target system # # @return [Hash] a hash list of local transfer files with its remote target directory def sync_files From a443b3b7d890da86163e3f778f1b3b27a1480862 Mon Sep 17 00:00:00 2001 From: Akos Murati Date: Fri, 13 Feb 2015 02:42:42 +1300 Subject: [PATCH 6/9] Removing pry --- lib/kitchen/transport/winrm.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/lib/kitchen/transport/winrm.rb b/lib/kitchen/transport/winrm.rb index 0c5910805..694fab746 100644 --- a/lib/kitchen/transport/winrm.rb +++ b/lib/kitchen/transport/winrm.rb @@ -28,10 +28,9 @@ end require "logger" -require 'pry' - require "kitchen/errors" require "kitchen/login_command" + module Kitchen module Transport @@ -328,7 +327,6 @@ def upload_file(local, remote) end logger.debug("Finished '#{remote}' Thread: #{Thread.current}") end - #binding.pry end # Checks to see if the target file on the guest is missing or out of date. @@ -361,9 +359,7 @@ def should_upload_file?(local, remote) return 1 EOH result = powershell(command) - #should = (powershell(command)[:exitcode] == 1) should = (result[:data][0][:stdout] == "1") - #binding.pry should end @@ -418,7 +414,6 @@ def decode_temp_file(local, remote) [System.IO.File]::WriteAllBytes($dest_file_path, $bytes) EOH raise_upload_error_if_failed(output, local, remote) - ##binding.pry end # Creates a guest file path equivalent from a host file path From 9d73f271d6080fa4c18521c2e52de4111b2b9737 Mon Sep 17 00:00:00 2001 From: Akos Murati Date: Fri, 13 Feb 2015 17:53:11 +1300 Subject: [PATCH 7/9] Adds exit condition if nothing to upload, for supporting dummy provisions --- lib/kitchen/transport/winrm.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/kitchen/transport/winrm.rb b/lib/kitchen/transport/winrm.rb index 694fab746..0d20dec4e 100644 --- a/lib/kitchen/transport/winrm.rb +++ b/lib/kitchen/transport/winrm.rb @@ -78,6 +78,8 @@ def wql(query) # (see Base#upload!) def upload!(local, remote) + return if local.nil? || local.empty? + logger.info("Concurrent threads set to :max_threads => #{config[:max_threads]}") logger.debug("Upload: #{local} -> #{remote}") local = Array.new(1) { local } if local.is_a? String From 95a92a29487dbdbc37ead7f700bd2413e64ba2e8 Mon Sep 17 00:00:00 2001 From: Akos Murati Date: Tue, 17 Feb 2015 01:40:10 +1300 Subject: [PATCH 8/9] Adds driver ssh_key to transport configuration --- lib/kitchen/data_munger.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/kitchen/data_munger.rb b/lib/kitchen/data_munger.rb index bec46147d..534c45eba 100644 --- a/lib/kitchen/data_munger.rb +++ b/lib/kitchen/data_munger.rb @@ -96,6 +96,7 @@ def transport_data_for(suite, platform) set_kitchen_config_at!(tdata, :kitchen_root) set_kitchen_config_at!(tdata, :test_base_path) set_kitchen_config_at!(tdata, :log_level) + tdata[:ssh_key] = data[:driver][:ssh_key] combine_arrays!(tdata, :run_list, :platform, :suite) end end From ea617d50a09a73b8bce87d4dd90b7da04c239f4c Mon Sep 17 00:00:00 2001 From: Akos Murati Date: Thu, 19 Feb 2015 19:50:27 +1300 Subject: [PATCH 9/9] Fixes new busser file-transfer for SSH --- lib/kitchen/busser.rb | 25 +++++++++++++------------ lib/kitchen/transport/ssh.rb | 4 ++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/lib/kitchen/busser.rb b/lib/kitchen/busser.rb index 13b6bf65c..c9ce52c3c 100644 --- a/lib/kitchen/busser.rb +++ b/lib/kitchen/busser.rb @@ -56,7 +56,7 @@ def initialize(suite_name, opts = {}) @config[:root_path] = opts.fetch(:root_path, DEFAULT_ROOT_PATH) @config[:version] = opts.fetch(:version, "busser") @config[:busser_bin] = opts.fetch(:busser_bin, File.join(@config[:root_path], "bin/busser")) - @config[:remote_transfer_path] = File.join(config[:root_path],'transfer') + @config[:remote_transfer_path] = opts.fetch(:remote_transfer_path, File.join(@config[:root_path], "transfer")) @config[:local_transfer_path] = nil end @@ -100,9 +100,12 @@ def cleanup_cmd case shell when "bourne" - cmd = <<-CMD.gsub(/^ {10}/, "") - rmdir -rf #{config[:remote_transfer_path]} - CMD + cmd = [ + sudo("rm -rf #{config[:remote_transfer_path]}"), + sudo("mkdir -p #{config[:remote_transfer_path]}"), + sudo("chmod 777 #{config[:remote_transfer_path]}") + ].join("\n").concat("\n").gsub(/^ {10}/, '') + when "powershell" cmd = <<-CMD.gsub(/^ {10}/, "") rmdir -Recurse -Force -ea 0 #{config[:remote_transfer_path]} | out-null @@ -121,18 +124,18 @@ def sync_files # Initialize a new transfer folder config[:local_transfer_path] = Dir.mktmpdir("#{instance.name}-busser-transfer") - fileList=Array.new + transfer_list = [] local_suite_files.each do |f| raw_content = IO.read(f) md5 = Digest::MD5.hexdigest(raw_content) remote_dir = config[:remote_transfer_path] - temp_file = File.join(config[:local_transfer_path],md5) - encoded_content = Base64.encode64(raw_content).gsub("\n", "") - IO.binwrite(temp_file,encoded_content) + temp_file = File.join(config[:local_transfer_path], md5) + encoded_content = Base64.encode64(raw_content).gsub("\n", '') + IO.binwrite(temp_file, encoded_content) - fileList.push({local: temp_file , remote: remote_dir}) + transfer_list.push({local: temp_file , remote: remote_dir}) end - fileList + transfer_list end # Returns a command string which installs Busser, and installs all @@ -253,8 +256,6 @@ def finalize_config!(instance) DEFAULT_RUBY_BINDIR = "/opt/chef/embedded/bin".freeze DEFAULT_ROOT_PATH = "/tmp/busser".freeze - BUSSER_TRANSFER_PATH = nil - # Loads any needed dependencies # # @raise [ClientError] if any library loading fails or any of the diff --git a/lib/kitchen/transport/ssh.rb b/lib/kitchen/transport/ssh.rb index 168caed0b..f41a216b1 100644 --- a/lib/kitchen/transport/ssh.rb +++ b/lib/kitchen/transport/ssh.rb @@ -46,6 +46,8 @@ def execute(command) # (see Base#upload!) def upload!(local, remote, options = {}, &progress) + return if local.nil? || local.empty? + options = { :recursive => true }.merge(options) if progress.nil? @@ -56,6 +58,8 @@ def upload!(local, remote, options = {}, &progress) } end + + local = Array.new(1) { local } if local.is_a? String local.each do |path| session.scp.upload!(path, remote, options, &progress) end