Skip to content

Instantly share code, notes, and snippets.

@KAllan357
Created April 16, 2013 18:18
Show Gist options
  • Save KAllan357/5398224 to your computer and use it in GitHub Desktop.
Save KAllan357/5398224 to your computer and use it in GitHub Desktop.
diff --git a/lib/ridley/host_connector/winrm/command_uploader.rb b/lib/ridley/host_connector/winrm/command_uploader.rb
index 728f7ed..f32b285 100644
--- a/lib/ridley/host_connector/winrm/command_uploader.rb
+++ b/lib/ridley/host_connector/winrm/command_uploader.rb
@@ -20,23 +20,27 @@ module Ridley
CHUNK_LIMIT = 1024
- # @return [String]
- attr_reader :command_string
# @return [WinRM::WinRMWebService]
attr_reader :winrm
+ # @return [String]
+ attr_reader :base64_file_name
+ # @return [String]
+ attr_reader :command_file_name
- # @param [String] command_string
# @param [WinRM::WinRMWebService] winrm
- def initialize(command_string, winrm)
- @command_string = command_string
- @winrm = winrm
+ def initialize(winrm)
+ @winrm = winrm
+ @base64_file_name = get_file_path("winrm-upload-base64-#{unique_string}")
+ @command_file_name = get_file_path("winrm-upload-#{unique_string}.bat")
end
# Uploads the command encoded as base64 to a file on the host
# and then uses Powershell to transform the base64 file into the
# command that was originally passed through.
- def upload
- upload_command
+ #
+ # @param [String] command_string
+ def upload(command_string)
+ upload_command(command_string)
convert_command
end
@@ -54,13 +58,13 @@ module Ridley
private
- def upload_command
- command_string_chars.each_slice(CHUNK_LIMIT) do |chunk|
+ def upload_command(command_string)
+ command_string_chars(command_string).each_slice(CHUNK_LIMIT) do |chunk|
winrm.run_cmd( "echo #{chunk.join} >> \"#{base64_file_name}\"" )
end
end
- def command_string_chars
+ def command_string_chars(command_string)
Base64.encode64(command_string).gsub("\n", '').chars.to_a
end
@@ -73,14 +77,6 @@ module Ridley
POWERSHELL
end
- def base64_file_name
- @base64_file_name ||= get_file_path("winrm-upload-base64-#{unique_string}")
- end
-
- def command_file_name
- @command_file_name ||= get_file_path("winrm-upload-#{unique_string}.bat")
- end
-
def unique_string
@unique_string ||= "#{Process.pid}-#{Time.now.to_i}"
end
diff --git a/lib/ridley/host_connector/winrm/worker.rb b/lib/ridley/host_connector/winrm/worker.rb
index 207d01e..3b25dba 100644
--- a/lib/ridley/host_connector/winrm/worker.rb
+++ b/lib/ridley/host_connector/winrm/worker.rb
@@ -19,6 +19,8 @@ module Ridley
attr_reader :winrm_endpoint
# @return [CommandUploader]
attr_reader :command_uploader
+ attr_reader :command_uploaders
+ finalizer :finalizer
EMBEDDED_RUBY_PATH = 'C:\opscode\chef\embedded\bin\ruby'.freeze
@@ -29,17 +31,23 @@ module Ridley
# * :password (String) the password for the user that will perform the bootstrap
# * :port (Fixnum) the winrm port to connect on the node the bootstrap will be performed on (5985)
def initialize(host, options = {})
- @options = options.deep_symbolize_keys
- @options = options[:winrm] if options[:winrm]
- @host = host
- @user = @options[:user]
- @password = @options[:password]
- @winrm_endpoint = "http://#{host}:#{winrm_port}/wsman"
+ @options = options.deep_symbolize_keys
+ @options = options[:winrm] if options[:winrm]
+ @host = host
+ @user = @options[:user]
+ @password = @options[:password]
+ @winrm_endpoint = "http://#{host}:#{winrm_port}/wsman"
+ @command_uploaders = Array.new
+ end
+
+ def finalizer
+ command_uploaders.map(&:cleanup)
end
def run(command)
- @command_uploader = CommandUploader.new(command, winrm)
- command = get_command(command)
+ command_uploader = CommandUploader.new(winrm)
+ command_uploaders << command_uploader
+ command = get_command(command, command_uploader)
response = Ridley::HostConnector::Response.new(host)
debug "Running WinRM Command: '#{command}' on: '#{host}' as: '#{user}'"
@@ -73,8 +81,6 @@ module Ridley
response.exit_code = -1
response.stderr = e.message
[ :error, response ]
- ensure
- command_uploader.cleanup
end
# @return [WinRM::WinRMWebService]
@@ -93,13 +99,13 @@ module Ridley
# @param command [String]
#
# @return [String]
- def get_command(command)
+ def get_command(command, command_uploader)
if command.length < CommandUploader::CHUNK_LIMIT
command
else
debug "Detected a command that was longer than #{CommandUploader::CHUNK_LIMIT} characters, \
uploading command as a file to the host."
- command_uploader.upload
+ command_uploader.upload(command)
command_uploader.command
end
end
diff --git a/spec/unit/ridley/host_connector/winrm/command_uploader_spec.rb b/spec/unit/ridley/host_connector/winrm/command_uploader_spec.rb
index c6f34aa..d8426a5 100644
--- a/spec/unit/ridley/host_connector/winrm/command_uploader_spec.rb
+++ b/spec/unit/ridley/host_connector/winrm/command_uploader_spec.rb
@@ -10,16 +10,19 @@ describe Ridley::HostConnector::WinRM::CommandUploader do
subject { command_uploader }
- let(:command_uploader) { described_class.new(command_string, winrm_stub) }
+ let(:command_uploader) { described_class.new(winrm_stub) }
let(:command_string) { "a" * 2048 }
let(:run_cmd_data) { { data: [{ stdout: "abc123" }] } }
let(:command_file_name) { "my_command.bat" }
- its(:command_string) { should eq(command_string) }
its(:winrm) { should eq(winrm_stub) }
+ before do
+ command_uploader.stub(:get_file_path).and_return("")
+ end
+
describe "#upload" do
- let(:upload) { command_uploader.upload }
+ let(:upload) { command_uploader.upload(command_string) }
it "calls winrm to upload and convert the command" do
winrm_stub.should_receive(:run_cmd).and_return(
diff --git a/spec/unit/ridley/host_connector/winrm/worker_spec.rb b/spec/unit/ridley/host_connector/winrm/worker_spec.rb
index d046e1b..9597f68 100644
--- a/spec/unit/ridley/host_connector/winrm/worker_spec.rb
+++ b/spec/unit/ridley/host_connector/winrm/worker_spec.rb
@@ -6,6 +6,10 @@ describe Ridley::HostConnector::WinRM::Worker do
let(:host) { 'reset.riotgames.com' }
let(:options) { {} }
+ before do
+ Ridley::HostConnector::WinRM::CommandUploader.stub(:new).and_return(double('command_uploader'))
+ end
+
describe "#winrm_port" do
subject(:winrm_port) { winrm_worker.winrm_port }
@@ -25,19 +29,15 @@ describe Ridley::HostConnector::WinRM::Worker do
end
describe "#get_command" do
- subject(:get_command) { winrm_worker.get_command(command) }
+ subject(:get_command) { winrm_worker.get_command(command, command_uploader_stub) }
let(:command) { "echo %TEMP%" }
+ let(:command_uploader_stub) { double('CommandUploader') }
it { should eq(command) }
context "when a command is more than 2047 characters" do
let(:command) { "a" * 2048 }
- let(:command_uploader_stub) { double('CommandUploader') }
-
- before do
- winrm_worker.stub(:command_uploader).and_return(command_uploader_stub)
- end
it "uploads and returns a command" do
Ridley::HostConnector::WinRM::CommandUploader.stub new: command_uploader_stub
diff --git a/spec/unit/ridley/host_connector/winrm_spec.rb b/spec/unit/ridley/host_connector/winrm_spec.rb
index ea47341..e34251f 100644
--- a/spec/unit/ridley/host_connector/winrm_spec.rb
+++ b/spec/unit/ridley/host_connector/winrm_spec.rb
@@ -10,11 +10,10 @@ describe Ridley::HostConnector::WinRM do
let(:node_two) do
Ridley::NodeResource.new(connection, automatic: { cloud: { public_hostname: "33.33.33.11" } })
end
- let(:command_uploader) { double('command_uploader') }
+ let(:command_uploader) { double('command_uploader', cleanup: nil) }
before do
Ridley::HostConnector::WinRM::CommandUploader.stub(:new).and_return(command_uploader)
- command_uploader.stub(:cleanup)
end
describe "ClassMethods" do
diff --git a/spec/unit/ridley/resources/node_resource_spec.rb b/spec/unit/ridley/resources/node_resource_spec.rb
index d626654..d0cebc6 100644
--- a/spec/unit/ridley/resources/node_resource_spec.rb
+++ b/spec/unit/ridley/resources/node_resource_spec.rb
@@ -159,6 +159,7 @@ describe Ridley::NodeResource do
context "when the best connector is WinRM" do
before do
Ridley::HostConnector.stub(:best_connector_for).and_yield(Ridley::HostConnector::WinRM)
+ Ridley::HostConnector::WinRM::CommandUploader.stub(:new)
end
it "returns a WinRm worker instance" do
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment