summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/mixlib/shellout/windows.rb15
-rw-r--r--mixlib-shellout.gemspec1
-rw-r--r--spec/mixlib/shellout_spec.rb13
3 files changed, 29 insertions, 0 deletions
diff --git a/lib/mixlib/shellout/windows.rb b/lib/mixlib/shellout/windows.rb
index 6003ae8..3661640 100644
--- a/lib/mixlib/shellout/windows.rb
+++ b/lib/mixlib/shellout/windows.rb
@@ -107,6 +107,9 @@ module Mixlib
# Kill the process
if (Time.now - start_wait) > timeout
begin
+ require 'wmi-lite/wmi'
+ wmi = WmiLite::Wmi.new
+ Utils.kill_process_tree(process.process_id, wmi)
Process.kill(:KILL, process.process_id)
rescue Errno::EIO
logger.warn("Failed to kill timed out process #{process.process_id}") if logger
@@ -313,6 +316,18 @@ module Mixlib
def self.executable?(path)
File.executable?(path) && !File.directory?(path)
end
+
+ def self.kill_process_tree(pid, wmi)
+ wmi.query("select ProcessID, Name from Win32_Process where ParentProcessID=#{pid}").each do |instance|
+ child_pid = instance.wmi_ole_object.processid
+ kill_process_tree(child_pid, wmi)
+ begin
+ Process.kill(:kill, child_pid)
+ rescue Errno::EIO
+ logger.warn("Failed to kill child process #{child_pid}::#{instance.wmi_ole_object.Name} of parent #{pid}") if logger
+ end
+ end
+ end
end
end # class
end
diff --git a/mixlib-shellout.gemspec b/mixlib-shellout.gemspec
index b35fe08..ed23fd1 100644
--- a/mixlib-shellout.gemspec
+++ b/mixlib-shellout.gemspec
@@ -14,6 +14,7 @@ Gem::Specification.new do |s|
s.required_ruby_version = ">= 1.9.3"
+ s.add_dependency "wmi-lite", "~> 1.0"
s.add_development_dependency "rspec", "~> 3.0"
s.bindir = "bin"
diff --git a/spec/mixlib/shellout_spec.rb b/spec/mixlib/shellout_spec.rb
index 2acdc3b..6b57619 100644
--- a/spec/mixlib/shellout_spec.rb
+++ b/spec/mixlib/shellout_spec.rb
@@ -1116,11 +1116,24 @@ describe Mixlib::ShellOut do
'powershell -c "sleep 10"'
end
+ before do
+ require "wmi-lite/wmi"
+ allow(WmiLite::Wmi).to receive(:new)
+ allow(Mixlib::ShellOut::Windows::Utils).to receive(:kill_process_tree)
+ end
+
it "should raise CommandTimeout" do
Timeout::timeout(5) do
expect { executed_cmd }.to raise_error(Mixlib::ShellOut::CommandTimeout)
end
end
+
+ context 'and child processes should be killed' do
+ it 'kills the child processes' do
+ expect(Mixlib::ShellOut::Windows::Utils).to receive(:kill_process_tree)
+ expect { executed_cmd }.to raise_error(Mixlib::ShellOut::CommandTimeout)
+ end
+ end
end
context 'on unix', :unix_only do