Hello community, here is the log from the commit of package rubygem-mixlib-shellout for openSUSE:Factory checked in at 2015-10-25 19:13:28 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rubygem-mixlib-shellout (Old) and /work/SRC/openSUSE:Factory/.rubygem-mixlib-shellout.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "rubygem-mixlib-shellout" Changes: -------- --- /work/SRC/openSUSE:Factory/rubygem-mixlib-shellout/rubygem-mixlib-shellout.changes 2015-09-27 08:38:53.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.rubygem-mixlib-shellout.new/rubygem-mixlib-shellout.changes 2015-10-25 19:13:30.000000000 +0100 @@ -1,0 +2,12 @@ +Sat Oct 24 04:30:04 UTC 2015 - co...@suse.com + +- updated to version 2.2.3 + no changelog found + +------------------------------------------------------------------- +Tue Oct 20 04:29:49 UTC 2015 - co...@suse.com + +- updated to version 2.2.2 + no changelog found + +------------------------------------------------------------------- Old: ---- mixlib-shellout-2.2.1.gem New: ---- mixlib-shellout-2.2.3.gem ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rubygem-mixlib-shellout.spec ++++++ --- /var/tmp/diff_new_pack.zYzOOp/_old 2015-10-25 19:13:31.000000000 +0100 +++ /var/tmp/diff_new_pack.zYzOOp/_new 2015-10-25 19:13:31.000000000 +0100 @@ -24,7 +24,7 @@ # Name: rubygem-mixlib-shellout -Version: 2.2.1 +Version: 2.2.3 Release: 0 %define mod_name mixlib-shellout %define mod_full_name %{mod_name}-%{version} ++++++ mixlib-shellout-2.2.1.gem -> mixlib-shellout-2.2.3.gem ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Gemfile new/Gemfile --- old/Gemfile 1970-01-01 01:00:00.000000000 +0100 +++ new/Gemfile 2015-10-23 01:48:41.000000000 +0200 @@ -0,0 +1,12 @@ +source 'https://rubygems.org' + +gemspec :name => "mixlib-shellout" + +group(:test) do + gem "rspec_junit_formatter" + gem 'rake' +end + +group(:development) do + gem 'pry' +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Rakefile new/Rakefile --- old/Rakefile 1970-01-01 01:00:00.000000000 +0100 +++ new/Rakefile 2015-10-23 01:48:41.000000000 +0200 @@ -0,0 +1,24 @@ +require 'rspec/core/rake_task' +require 'rubygems/package_task' +require 'mixlib/shellout/version' + +Dir[File.expand_path("../*gemspec", __FILE__)].reverse.each do |gemspec_path| + gemspec = eval(IO.read(gemspec_path)) + Gem::PackageTask.new(gemspec).define +end + +desc "Run all specs in spec directory" +RSpec::Core::RakeTask.new(:spec) do |t| + t.pattern = FileList['spec/**/*_spec.rb'] +end + +desc "Build it and ship it" +task ship: [:clobber_package, :gem] do + sh("git tag #{Mixlib::ShellOut::VERSION}") + sh("git push opscode --tags") + Dir[File.expand_path("../pkg/*.gem", __FILE__)].reverse.each do |built_gem| + sh("gem push #{built_gem}") + end +end + +task default: :spec Files old/checksums.yaml.gz and new/checksums.yaml.gz differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/mixlib/shellout/version.rb new/lib/mixlib/shellout/version.rb --- old/lib/mixlib/shellout/version.rb 2015-09-12 00:55:24.000000000 +0200 +++ new/lib/mixlib/shellout/version.rb 2015-10-23 01:48:41.000000000 +0200 @@ -1,5 +1,5 @@ module Mixlib class ShellOut - VERSION = "2.2.1" + VERSION = "2.2.3" end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/mixlib/shellout/windows/core_ext.rb new/lib/mixlib/shellout/windows/core_ext.rb --- old/lib/mixlib/shellout/windows/core_ext.rb 2015-09-12 00:55:24.000000000 +0200 +++ new/lib/mixlib/shellout/windows/core_ext.rb 2015-10-23 01:48:41.000000000 +0200 @@ -21,6 +21,8 @@ # Add new constants for Logon module Process::Constants + private + LOGON32_LOGON_INTERACTIVE = 0x00000002 LOGON32_PROVIDER_DEFAULT = 0x00000000 UOI_NAME = 0x00000002 @@ -34,16 +36,6 @@ # Define the functions needed to check with Service windows station module Process::Functions - module FFI::Library - # Wrapper method for attach_function + private - def attach_pfunc(*args) - attach_function(*args) - private args[0] - end - end - - extend FFI::Library - ffi_lib :advapi32 attach_pfunc :LogonUserW, @@ -64,315 +56,316 @@ # Override Process.create to check for running in the Service window station and doing # a full logon with LogonUser, instead of a CreateProcessWithLogon +# Cloned from https://github.com/djberg96/win32-process/blob/ffi/lib/win32/process.rb +# as of 2015-10-15 from commit cc066e5df25048f9806a610f54bf5f7f253e86f7 module Process - include Process::Constants - include Process::Structs - def create(args) - unless args.kind_of?(Hash) - raise TypeError, 'hash keyword arguments expected' - end + # Explicitly reopen singleton class so that class/constant declarations from + # extensions are visible in Modules.nesting. + class << self + def create(args) + unless args.kind_of?(Hash) + raise TypeError, 'hash keyword arguments expected' + end + + valid_keys = %w[ + app_name command_line inherit creation_flags cwd environment + startup_info thread_inherit process_inherit close_handles with_logon + domain password + ] + + valid_si_keys = %w[ + startf_flags desktop title x y x_size y_size x_count_chars + y_count_chars fill_attribute sw_flags stdin stdout stderr + ] + + # Set default values + hash = { + 'app_name' => nil, + 'creation_flags' => 0, + 'close_handles' => true + } - valid_keys = %w[ - app_name command_line inherit creation_flags cwd environment - startup_info thread_inherit process_inherit close_handles with_logon - domain password - ] - - valid_si_keys = %w[ - startf_flags desktop title x y x_size y_size x_count_chars - y_count_chars fill_attribute sw_flags stdin stdout stderr - ] - - # Set default values - hash = { - 'app_name' => nil, - 'creation_flags' => 0, - 'close_handles' => true - } - - # Validate the keys, and convert symbols and case to lowercase strings. - args.each{ |key, val| - key = key.to_s.downcase - unless valid_keys.include?(key) - raise ArgumentError, "invalid key '#{key}'" - end - hash[key] = val - } - - si_hash = {} - - # If the startup_info key is present, validate its subkeys - if hash['startup_info'] - hash['startup_info'].each{ |key, val| + # Validate the keys, and convert symbols and case to lowercase strings. + args.each{ |key, val| key = key.to_s.downcase - unless valid_si_keys.include?(key) - raise ArgumentError, "invalid startup_info key '#{key}'" + unless valid_keys.include?(key) + raise ArgumentError, "invalid key '#{key}'" end - si_hash[key] = val + hash[key] = val } - end - # The +command_line+ key is mandatory unless the +app_name+ key - # is specified. - unless hash['command_line'] - if hash['app_name'] - hash['command_line'] = hash['app_name'] - hash['app_name'] = nil - else - raise ArgumentError, 'command_line or app_name must be specified' - end - end + si_hash = {} - env = nil - - # The env string should be passed as a string of ';' separated paths. - if hash['environment'] - env = hash['environment'] + # If the startup_info key is present, validate its subkeys + if hash['startup_info'] + hash['startup_info'].each{ |key, val| + key = key.to_s.downcase + unless valid_si_keys.include?(key) + raise ArgumentError, "invalid startup_info key '#{key}'" + end + si_hash[key] = val + } + end - unless env.respond_to?(:join) - env = hash['environment'].split(File::PATH_SEPARATOR) + # The +command_line+ key is mandatory unless the +app_name+ key + # is specified. + unless hash['command_line'] + if hash['app_name'] + hash['command_line'] = hash['app_name'] + hash['app_name'] = nil + else + raise ArgumentError, 'command_line or app_name must be specified' + end end - env = env.map{ |e| e + 0.chr }.join('') + 0.chr - env.to_wide_string! if hash['with_logon'] - end + env = nil - # Process SECURITY_ATTRIBUTE structure - process_security = nil + # The env string should be passed as a string of ';' separated paths. + if hash['environment'] + env = hash['environment'] - if hash['process_inherit'] - process_security = SECURITY_ATTRIBUTES.new - process_security[:nLength] = 12 - process_security[:bInheritHandle] = true - end + unless env.respond_to?(:join) + env = hash['environment'].split(File::PATH_SEPARATOR) + end - # Thread SECURITY_ATTRIBUTE structure - thread_security = nil + env = env.map{ |e| e + 0.chr }.join('') + 0.chr + env.to_wide_string! if hash['with_logon'] + end - if hash['thread_inherit'] - thread_security = SECURITY_ATTRIBUTES.new - thread_security[:nLength] = 12 - thread_security[:bInheritHandle] = true - end + # Process SECURITY_ATTRIBUTE structure + process_security = nil - # Automatically handle stdin, stdout and stderr as either IO objects - # or file descriptors. This won't work for StringIO, however. It also - # will not work on JRuby because of the way it handles internal file - # descriptors. - # - ['stdin', 'stdout', 'stderr'].each{ |io| - if si_hash[io] - if si_hash[io].respond_to?(:fileno) - handle = get_osfhandle(si_hash[io].fileno) - else - handle = get_osfhandle(si_hash[io]) - end + if hash['process_inherit'] + process_security = SECURITY_ATTRIBUTES.new + process_security[:nLength] = 12 + process_security[:bInheritHandle] = 1 + end - if handle == INVALID_HANDLE_VALUE - ptr = FFI::MemoryPointer.new(:int) + # Thread SECURITY_ATTRIBUTE structure + thread_security = nil - if windows_version >= 6 && get_errno(ptr) == 0 - errno = ptr.read_int + if hash['thread_inherit'] + thread_security = SECURITY_ATTRIBUTES.new + thread_security[:nLength] = 12 + thread_security[:bInheritHandle] = 1 + end + + # Automatically handle stdin, stdout and stderr as either IO objects + # or file descriptors. This won't work for StringIO, however. It also + # will not work on JRuby because of the way it handles internal file + # descriptors. + # + ['stdin', 'stdout', 'stderr'].each{ |io| + if si_hash[io] + if si_hash[io].respond_to?(:fileno) + handle = get_osfhandle(si_hash[io].fileno) else - errno = FFI.errno + handle = get_osfhandle(si_hash[io]) end - raise SystemCallError.new("get_osfhandle", errno) - end + if handle == INVALID_HANDLE_VALUE + ptr = FFI::MemoryPointer.new(:int) - # Most implementations of Ruby on Windows create inheritable - # handles by default, but some do not. RF bug #26988. - bool = SetHandleInformation( - handle, - HANDLE_FLAG_INHERIT, - HANDLE_FLAG_INHERIT - ) + if windows_version >= 6 && get_errno(ptr) == 0 + errno = ptr.read_int + else + errno = FFI.errno + end - raise SystemCallError.new("SetHandleInformation", FFI.errno) unless bool + raise SystemCallError.new("get_osfhandle", errno) + end - si_hash[io] = handle - si_hash['startf_flags'] ||= 0 - si_hash['startf_flags'] |= STARTF_USESTDHANDLES - hash['inherit'] = true - end - } - - procinfo = PROCESS_INFORMATION.new - startinfo = STARTUPINFO.new - - unless si_hash.empty? - startinfo[:cb] = startinfo.size - startinfo[:lpDesktop] = si_hash['desktop'] if si_hash['desktop'] - startinfo[:lpTitle] = si_hash['title'] if si_hash['title'] - startinfo[:dwX] = si_hash['x'] if si_hash['x'] - startinfo[:dwY] = si_hash['y'] if si_hash['y'] - startinfo[:dwXSize] = si_hash['x_size'] if si_hash['x_size'] - startinfo[:dwYSize] = si_hash['y_size'] if si_hash['y_size'] - startinfo[:dwXCountChars] = si_hash['x_count_chars'] if si_hash['x_count_chars'] - startinfo[:dwYCountChars] = si_hash['y_count_chars'] if si_hash['y_count_chars'] - startinfo[:dwFillAttribute] = si_hash['fill_attribute'] if si_hash['fill_attribute'] - startinfo[:dwFlags] = si_hash['startf_flags'] if si_hash['startf_flags'] - startinfo[:wShowWindow] = si_hash['sw_flags'] if si_hash['sw_flags'] - startinfo[:cbReserved2] = 0 - startinfo[:hStdInput] = si_hash['stdin'] if si_hash['stdin'] - startinfo[:hStdOutput] = si_hash['stdout'] if si_hash['stdout'] - startinfo[:hStdError] = si_hash['stderr'] if si_hash['stderr'] - end + # Most implementations of Ruby on Windows create inheritable + # handles by default, but some do not. RF bug #26988. + bool = SetHandleInformation( + handle, + HANDLE_FLAG_INHERIT, + HANDLE_FLAG_INHERIT + ) - app = nil - cmd = nil + raise SystemCallError.new("SetHandleInformation", FFI.errno) unless bool - # Convert strings to wide character strings if present - if hash['app_name'] - app = hash['app_name'].to_wide_string - end + si_hash[io] = handle + si_hash['startf_flags'] ||= 0 + si_hash['startf_flags'] |= STARTF_USESTDHANDLES + hash['inherit'] = true + end + } - if hash['command_line'] - cmd = hash['command_line'].to_wide_string - end + procinfo = PROCESS_INFORMATION.new + startinfo = STARTUPINFO.new - if hash['cwd'] - cwd = hash['cwd'].to_wide_string - end + unless si_hash.empty? + startinfo[:cb] = startinfo.size + startinfo[:lpDesktop] = si_hash['desktop'] if si_hash['desktop'] + startinfo[:lpTitle] = si_hash['title'] if si_hash['title'] + startinfo[:dwX] = si_hash['x'] if si_hash['x'] + startinfo[:dwY] = si_hash['y'] if si_hash['y'] + startinfo[:dwXSize] = si_hash['x_size'] if si_hash['x_size'] + startinfo[:dwYSize] = si_hash['y_size'] if si_hash['y_size'] + startinfo[:dwXCountChars] = si_hash['x_count_chars'] if si_hash['x_count_chars'] + startinfo[:dwYCountChars] = si_hash['y_count_chars'] if si_hash['y_count_chars'] + startinfo[:dwFillAttribute] = si_hash['fill_attribute'] if si_hash['fill_attribute'] + startinfo[:dwFlags] = si_hash['startf_flags'] if si_hash['startf_flags'] + startinfo[:wShowWindow] = si_hash['sw_flags'] if si_hash['sw_flags'] + startinfo[:cbReserved2] = 0 + startinfo[:hStdInput] = si_hash['stdin'] if si_hash['stdin'] + startinfo[:hStdOutput] = si_hash['stdout'] if si_hash['stdout'] + startinfo[:hStdError] = si_hash['stderr'] if si_hash['stderr'] + end - inherit = hash['inherit'] || false + app = nil + cmd = nil - if hash['with_logon'] - logon = hash['with_logon'].to_wide_string + # Convert strings to wide character strings if present + if hash['app_name'] + app = hash['app_name'].to_wide_string + end - if hash['password'] - passwd = hash['password'].to_wide_string - else - raise ArgumentError, 'password must be specified if with_logon is used' + if hash['command_line'] + cmd = hash['command_line'].to_wide_string end - if hash['domain'] - domain = hash['domain'].to_wide_string + if hash['cwd'] + cwd = hash['cwd'].to_wide_string end - hash['creation_flags'] |= CREATE_UNICODE_ENVIRONMENT + inherit = hash['inherit'] ? 1 : 0 - winsta_name = FFI::MemoryPointer.new(:char, 256) - return_size = FFI::MemoryPointer.new(:ulong) + if hash['with_logon'] + logon = hash['with_logon'].to_wide_string - bool = GetUserObjectInformationA( - GetProcessWindowStation(), # Window station handle - UOI_NAME, # Information to get - winsta_name, # Buffer to receive information - winsta_name.size, # Size of buffer - return_size # Size filled into buffer - ) + if hash['password'] + passwd = hash['password'].to_wide_string + else + raise ArgumentError, 'password must be specified if with_logon is used' + end - unless bool - raise SystemCallError.new("GetUserObjectInformationA", FFI.errno) - end + if hash['domain'] + domain = hash['domain'].to_wide_string + end - winsta_name = winsta_name.read_string(return_size.read_ulong) + hash['creation_flags'] |= CREATE_UNICODE_ENVIRONMENT - # If running in the service windows station must do a log on to get - # to the interactive desktop. Running process user account must have - # the 'Replace a process level token' permission. This is necessary as - # the logon (which happens with CreateProcessWithLogon) must have an - # interactive windows station to attach to, which is created with the - # LogonUser cann with the LOGON32_LOGON_INTERACTIVE flag. - if winsta_name =~ /^Service-0x0-.*$/i - token = FFI::MemoryPointer.new(:ulong) - - bool = LogonUserW( - logon, # User - domain, # Domain - passwd, # Password - LOGON32_LOGON_INTERACTIVE, # Logon Type - LOGON32_PROVIDER_DEFAULT, # Logon Provider - token # User token handle + winsta_name = FFI::MemoryPointer.new(:char, 256) + return_size = FFI::MemoryPointer.new(:ulong) + + bool = GetUserObjectInformationA( + GetProcessWindowStation(), # Window station handle + UOI_NAME, # Information to get + winsta_name, # Buffer to receive information + winsta_name.size, # Size of buffer + return_size # Size filled into buffer ) unless bool - raise SystemCallError.new("LogonUserW", FFI.errno) + raise SystemCallError.new("GetUserObjectInformationA", FFI.errno) end - token = token.read_ulong + winsta_name = winsta_name.read_string(return_size.read_ulong) + + # If running in the service windows station must do a log on to get + # to the interactive desktop. Running process user account must have + # the 'Replace a process level token' permission. This is necessary as + # the logon (which happens with CreateProcessWithLogon) must have an + # interactive windows station to attach to, which is created with the + # LogonUser cann with the LOGON32_LOGON_INTERACTIVE flag. + if winsta_name =~ /^Service-0x0-.*$/i + token = FFI::MemoryPointer.new(:ulong) + + bool = LogonUserW( + logon, # User + domain, # Domain + passwd, # Password + LOGON32_LOGON_INTERACTIVE, # Logon Type + LOGON32_PROVIDER_DEFAULT, # Logon Provider + token # User token handle + ) + + unless bool + raise SystemCallError.new("LogonUserW", FFI.errno) + end + + token = token.read_ulong - begin - bool = CreateProcessAsUserW( - token, # User token handle + begin + bool = CreateProcessAsUserW( + token, # User token handle + app, # App name + cmd, # Command line + process_security, # Process attributes + thread_security, # Thread attributes + inherit, # Inherit handles + hash['creation_flags'], # Creation Flags + env, # Environment + cwd, # Working directory + startinfo, # Startup Info + procinfo # Process Info + ) + ensure + CloseHandle(token) + end + + unless bool + raise SystemCallError.new("CreateProcessAsUserW (You must hold the 'Replace a process level token' permission)", FFI.errno) + end + else + bool = CreateProcessWithLogonW( + logon, # User + domain, # Domain + passwd, # Password + LOGON_WITH_PROFILE, # Logon flags app, # App name cmd, # Command line - process_security, # Process attributes - thread_security, # Thread attributes - inherit, # Inherit handles - hash['creation_flags'], # Creation Flags + hash['creation_flags'], # Creation flags env, # Environment cwd, # Working directory startinfo, # Startup Info procinfo # Process Info ) - ensure - CloseHandle(token) - end - unless bool - raise SystemCallError.new("CreateProcessAsUserW (You must hold the 'Replace a process level token' permission)", FFI.errno) + unless bool + raise SystemCallError.new("CreateProcessWithLogonW", FFI.errno) + end end else - bool = CreateProcessWithLogonW( - logon, # User - domain, # Domain - passwd, # Password - LOGON_WITH_PROFILE, # Logon flags + bool = CreateProcessW( app, # App name cmd, # Command line + process_security, # Process attributes + thread_security, # Thread attributes + inherit, # Inherit handles? hash['creation_flags'], # Creation flags env, # Environment cwd, # Working directory startinfo, # Startup Info procinfo # Process Info ) - end - unless bool - raise SystemCallError.new("CreateProcessWithLogonW", FFI.errno) + unless bool + raise SystemCallError.new("CreateProcessW", FFI.errno) + end end - else - bool = CreateProcessW( - app, # App name - cmd, # Command line - process_security, # Process attributes - thread_security, # Thread attributes - inherit, # Inherit handles? - hash['creation_flags'], # Creation flags - env, # Environment - cwd, # Working directory - startinfo, # Startup Info - procinfo # Process Info - ) - unless bool - raise SystemCallError.new("CreateProcessW", FFI.errno) + # Automatically close the process and thread handles in the + # PROCESS_INFORMATION struct unless explicitly told not to. + if hash['close_handles'] + CloseHandle(procinfo[:hProcess]) + CloseHandle(procinfo[:hThread]) + # Clear these fields so callers don't attempt to close the handle + # which can result in the wrong handle being closed or an + # exception in some circumstances. + procinfo[:hProcess] = 0 + procinfo[:hThread] = 0 end - end - # Automatically close the process and thread handles in the - # PROCESS_INFORMATION struct unless explicitly told not to. - if hash['close_handles'] - CloseHandle(procinfo[:hProcess]) if procinfo[:hProcess] - CloseHandle(procinfo[:hThread]) if procinfo[:hThread] - - # Set fields to nil so callers don't attempt to close the handle - # which can result in the wrong handle being closed or an - # exception in some circumstances - procinfo[:hProcess] = nil - procinfo[:hThread] = nil + ProcessInfo.new( + procinfo[:hProcess], + procinfo[:hThread], + procinfo[:dwProcessId], + procinfo[:dwThreadId] + ) end - - ProcessInfo.new( - procinfo[:hProcess], - procinfo[:hThread], - procinfo[:dwProcessId], - procinfo[:dwThreadId] - ) end - - module_function :create end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lib/mixlib/shellout/windows.rb new/lib/mixlib/shellout/windows.rb --- old/lib/mixlib/shellout/windows.rb 2015-09-12 00:55:24.000000000 +0200 +++ new/lib/mixlib/shellout/windows.rb 2015-10-23 01:48:41.000000000 +0200 @@ -43,7 +43,6 @@ # Missing lots of features from the UNIX version, such as # uid, etc. def run_command - # # Create pipes to capture stdout and stderr, # @@ -79,6 +78,7 @@ # Start the process # process = Process.create(create_process_args) + logger.debug(Utils.format_process(process, app_name, command_line, timeout)) if logger begin # Start pushing data into input stdin_write << input if input @@ -107,12 +107,19 @@ # 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, logger) Process.kill(:KILL, process.process_id) - rescue Errno::EIO + rescue Errno::EIO, SystemCallError logger.warn("Failed to kill timed out process #{process.process_id}") if logger end - raise Mixlib::ShellOut::CommandTimeout, "command timed out:\n#{format_for_exception}" + raise Mixlib::ShellOut::CommandTimeout, [ + "command timed out:", + format_for_exception, + Utils.format_process(process, app_name, command_line, timeout) + ].join("\n") end consume_output(open_streams, stdout_read, stderr_read) @@ -313,6 +320,42 @@ def self.executable?(path) File.executable?(path) && !File.directory?(path) end + + # recursively kills all child processes of given pid + # calls itself querying for children child procs until + # none remain. Important that a single WmiLite instance + # is passed in since each creates its own WMI rpc process + def self.kill_process_tree(pid, wmi, logger) + wmi.query("select * from Win32_Process where ParentProcessID=#{pid}").each do |instance| + child_pid = instance.wmi_ole_object.processid + kill_process_tree(child_pid, wmi, logger) + begin + logger.debug([ + "killing child process #{child_pid}::", + "#{instance.wmi_ole_object.Name} of parent #{pid}" + ].join) if logger + kill_process(instance) + rescue Errno::EIO, SystemCallError + logger.debug([ + "Failed to kill child process #{child_pid}::", + "#{instance.wmi_ole_object.Name} of parent #{pid}" + ].join) if logger + end + end + end + + def self.kill_process(instance) + Process.kill(:KILL, instance.wmi_ole_object.processid) + end + + def self.format_process(process, app_name, command_line, timeout) + msg = [] + msg << "ProcessId: #{process.process_id}" + msg << "app_name: #{app_name}" + msg << "command_line: #{command_line}" + msg << "timeout: #{timeout}" + msg.join("\n") + end end end # class end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/metadata new/metadata --- old/metadata 2015-09-12 00:55:24.000000000 +0200 +++ new/metadata 2015-10-23 01:48:41.000000000 +0200 @@ -1,14 +1,14 @@ --- !ruby/object:Gem::Specification name: mixlib-shellout version: !ruby/object:Gem::Version - version: 2.2.1 + version: 2.2.3 platform: ruby authors: - Opscode autorequire: bindir: bin cert_chain: [] -date: 2015-09-11 00:00:00.000000000 Z +date: 2015-10-22 00:00:00.000000000 Z dependencies: - !ruby/object:Gem::Dependency name: rspec @@ -32,14 +32,18 @@ - README.md - LICENSE files: +- Gemfile - LICENSE - README.md +- Rakefile - lib/mixlib/shellout.rb - lib/mixlib/shellout/exceptions.rb - lib/mixlib/shellout/unix.rb - lib/mixlib/shellout/version.rb - lib/mixlib/shellout/windows.rb - lib/mixlib/shellout/windows/core_ext.rb +- mixlib-shellout-windows.gemspec +- mixlib-shellout.gemspec homepage: http://wiki.opscode.com/ licenses: [] metadata: {} @@ -59,8 +63,9 @@ version: '0' requirements: [] rubyforge_project: -rubygems_version: 2.4.4 +rubygems_version: 2.4.8 signing_key: specification_version: 4 summary: Run external commands on Unix or Windows test_files: [] +has_rdoc: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mixlib-shellout-windows.gemspec new/mixlib-shellout-windows.gemspec --- old/mixlib-shellout-windows.gemspec 1970-01-01 01:00:00.000000000 +0100 +++ new/mixlib-shellout-windows.gemspec 2015-10-23 01:48:41.000000000 +0200 @@ -0,0 +1,8 @@ +gemspec = eval(File.read(File.expand_path("../mixlib-shellout.gemspec", __FILE__))) + +gemspec.platform = Gem::Platform.new(["universal", "mingw32"]) + +gemspec.add_dependency "win32-process", "~> 0.8.2" +gemspec.add_dependency "wmi-lite", "~> 1.0" + +gemspec diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mixlib-shellout.gemspec new/mixlib-shellout.gemspec --- old/mixlib-shellout.gemspec 1970-01-01 01:00:00.000000000 +0100 +++ new/mixlib-shellout.gemspec 2015-10-23 01:48:41.000000000 +0200 @@ -0,0 +1,24 @@ +$:.unshift(File.dirname(__FILE__) + '/lib') +require 'mixlib/shellout/version' + +Gem::Specification.new do |s| + s.name = 'mixlib-shellout' + s.version = Mixlib::ShellOut::VERSION + s.platform = Gem::Platform::RUBY + s.extra_rdoc_files = ["README.md", "LICENSE" ] + s.summary = "Run external commands on Unix or Windows" + s.description = s.summary + s.author = "Opscode" + s.email = "i...@opscode.com" + s.homepage = "http://wiki.opscode.com/" + + s.required_ruby_version = ">= 1.9.3" + + s.add_development_dependency "rspec", "~> 3.0" + + s.bindir = "bin" + s.executables = [] + s.require_path = 'lib' + s.files = %w(Gemfile Rakefile LICENSE README.md) + Dir.glob("*.gemspec") + + Dir.glob("lib/**/*", File::FNM_DOTMATCH).reject {|f| File.directory?(f) } +end