mixlib-shellout 1.2.0-x86-mingw32 → 1.3.0.rc.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NmI4YTJhYTFjMDhjY2YzZDY3Njk3ZDdhZjg5ZGFhMmFjM2NhODNhNA==
5
+ data.tar.gz: !binary |-
6
+ YmU5Y2E4NDgyMDQxZjIzMzRkMmNhNDFiZTVhNmI1MzIwZTM1OTQxMQ==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NDQ0ZjlmMzllMTM5ZDJkYTI1ZTY0ZGY1YTRmOTUzMGRlNDUwMmM0YjAyOWI2
10
+ NjFhYWIzYzJhMTc1NzZjOGJlMDhmMDc4YTYwNjk5YWU3NzJkZDJkYmQxN2Fj
11
+ M2FlN2VjZjY3YjBlM2ZlNDkxZWZjY2M5MjNmM2Q1NWExOGEwOTQ=
12
+ data.tar.gz: !binary |-
13
+ ZWVkYTc1M2E1YjM5NWVlOTgzMDQyM2Y5YmY0NGMwMWM2MDFhNGNkNjY2YjU0
14
+ NzQ0MTRjNTViOTA4OGZhZGViMjhmNDhjNTI0ODQyMDkxOTNmNDRkODE4MjA3
15
+ ZDRkOWY5NmMwNDI0ODQwZjUyZWIzNzE5YWIzMDJhNDdkODcyYjQ=
@@ -154,6 +154,7 @@ module Mixlib
154
154
  @environment = DEFAULT_ENVIRONMENT
155
155
  @cwd = nil
156
156
  @valid_exit_codes = [0]
157
+ @terminate_reason = nil
157
158
 
158
159
  if command_args.last.is_a?(Hash)
159
160
  parse_options(command_args.pop)
@@ -191,6 +192,7 @@ module Mixlib
191
192
  # results when the command exited with an unexpected status.
192
193
  def format_for_exception
193
194
  msg = ""
195
+ msg << "#{@terminate_reason}\n" if @terminate_reason
194
196
  msg << "---- Begin output of #{command} ----\n"
195
197
  msg << "STDOUT: #{stdout.strip}\n"
196
198
  msg << "STDERR: #{stderr.strip}\n"
@@ -38,6 +38,7 @@ module Mixlib
38
38
  # within +timeout+ seconds (default: 600s)
39
39
  def run_command
40
40
  @child_pid = fork_subprocess
41
+ @reaped = false
41
42
 
42
43
  configure_parent_process_file_descriptors
43
44
 
@@ -57,36 +58,33 @@ module Mixlib
57
58
  write_to_child_stdin
58
59
 
59
60
  until @status
60
- ready = IO.select(open_pipes, nil, nil, READ_WAIT_TIME)
61
- unless ready
61
+ ready_buffers = attempt_buffer_read
62
+ unless ready_buffers
62
63
  @execution_time += READ_WAIT_TIME
63
64
  if @execution_time >= timeout && !@result
64
- raise CommandTimeout, "command timed out:\n#{format_for_exception}"
65
+ # kill the bad proccess
66
+ reap_errant_child
67
+ # read anything it wrote when we killed it
68
+ attempt_buffer_read
69
+ # raise
70
+ raise CommandTimeout, "Command timed out after #{@execution_time.to_i}s:\n#{format_for_exception}"
65
71
  end
66
72
  end
67
73
 
68
- if ready && ready.first.include?(child_stdout)
69
- read_stdout_to_buffer
70
- end
71
- if ready && ready.first.include?(child_stderr)
72
- read_stderr_to_buffer
73
- end
74
-
75
- unless @status
76
- # make one more pass to get the last of the output after the
77
- # child process dies
78
- if results = Process.waitpid2(@child_pid, Process::WNOHANG)
79
- @status = results.last
80
- redo
81
- end
82
- end
74
+ attempt_reap
83
75
  end
76
+
84
77
  self
85
- rescue Exception
86
- # do our best to kill zombies
87
- Process.waitpid2(@child_pid, Process::WNOHANG) rescue nil
78
+ rescue Errno::ENOENT
79
+ # When ENOENT happens, we can be reasonably sure that the child process
80
+ # is going to exit quickly, so we use the blocking variant of waitpid2
81
+ reap
88
82
  raise
89
83
  ensure
84
+ reap_errant_child if should_reap?
85
+ # make one more pass to get the last of the output after the
86
+ # child process dies
87
+ attempt_buffer_read
90
88
  # no matter what happens, turn the GC back on, and hope whatever busted
91
89
  # version of ruby we're on doesn't allocate some objects during the next
92
90
  # GC run.
@@ -231,6 +229,17 @@ module Mixlib
231
229
  child_stdin.close # Kick things off
232
230
  end
233
231
 
232
+ def attempt_buffer_read
233
+ ready = IO.select(open_pipes, nil, nil, READ_WAIT_TIME)
234
+ if ready && ready.first.include?(child_stdout)
235
+ read_stdout_to_buffer
236
+ end
237
+ if ready && ready.first.include?(child_stderr)
238
+ read_stderr_to_buffer
239
+ end
240
+ ready
241
+ end
242
+
234
243
  def read_stdout_to_buffer
235
244
  while chunk = child_stdout.read_nonblock(READ_SIZE)
236
245
  @stdout << chunk
@@ -291,6 +300,44 @@ module Mixlib
291
300
  end
292
301
  end
293
302
 
303
+ def reap_errant_child
304
+ return if attempt_reap
305
+ @terminate_reason = "Command execeded allowed execution time, killed by TERM signal."
306
+ logger.error("Command execeded allowed execution time, sending TERM") if logger
307
+ Process.kill(:TERM, @child_pid)
308
+ sleep 3
309
+ return if attempt_reap
310
+ @terminate_reason = "Command execeded allowed execution time, did not respond to TERM. Killed by KILL signal."
311
+ logger.error("Command did not exit from TERM, sending KILL") if logger
312
+ Process.kill(:KILL, @child_pid)
313
+ reap
314
+
315
+ # Should not hit this but it's possible if something is calling waitall
316
+ # in a separate thread.
317
+ rescue Errno::ESRCH
318
+ nil
319
+ end
320
+
321
+ def should_reap?
322
+ # if we fail to fork, no child pid so nothing to reap
323
+ @child_pid && !@reaped
324
+ end
325
+
326
+ def reap
327
+ results = Process.waitpid2(@child_pid)
328
+ @reaped = true
329
+ @status = results.last
330
+ end
331
+
332
+ def attempt_reap
333
+ if results = Process.waitpid2(@child_pid, Process::WNOHANG)
334
+ @reaped = true
335
+ @status = results.last
336
+ else
337
+ nil
338
+ end
339
+ end
340
+
294
341
  end
295
342
  end
296
343
  end
@@ -1,5 +1,5 @@
1
1
  module Mixlib
2
2
  class ShellOut
3
- VERSION = "1.2.0"
3
+ VERSION = "1.3.0.rc.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,68 +1,46 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixlib-shellout
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
5
- prerelease:
4
+ version: 1.3.0.rc.0
6
5
  platform: x86-mingw32
7
6
  authors:
8
7
  - Opscode
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-07-19 00:00:00.000000000 Z
11
+ date: 2013-11-19 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rspec
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
22
- type: :development
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ! '>='
28
- - !ruby/object:Gem::Version
29
- version: '0'
30
- - !ruby/object:Gem::Dependency
31
- name: ap
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ! '>='
17
+ - - ~>
36
18
  - !ruby/object:Gem::Version
37
- version: '0'
19
+ version: '2.0'
38
20
  type: :development
39
21
  prerelease: false
40
22
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
23
  requirements:
43
- - - ! '>='
24
+ - - ~>
44
25
  - !ruby/object:Gem::Version
45
- version: '0'
26
+ version: '2.0'
46
27
  - !ruby/object:Gem::Dependency
47
28
  name: win32-process
48
29
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
30
  requirements:
51
31
  - - ~>
52
32
  - !ruby/object:Gem::Version
53
- version: 0.7.0
33
+ version: 0.7.1
54
34
  type: :runtime
55
35
  prerelease: false
56
36
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
37
  requirements:
59
38
  - - ~>
60
39
  - !ruby/object:Gem::Version
61
- version: 0.7.0
40
+ version: 0.7.1
62
41
  - !ruby/object:Gem::Dependency
63
42
  name: windows-pr
64
43
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
44
  requirements:
67
45
  - - ~>
68
46
  - !ruby/object:Gem::Version
@@ -70,7 +48,6 @@ dependencies:
70
48
  type: :runtime
71
49
  prerelease: false
72
50
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
51
  requirements:
75
52
  - - ~>
76
53
  - !ruby/object:Gem::Version
@@ -93,26 +70,25 @@ files:
93
70
  - lib/mixlib/shellout.rb
94
71
  homepage: http://wiki.opscode.com/
95
72
  licenses: []
73
+ metadata: {}
96
74
  post_install_message:
97
75
  rdoc_options: []
98
76
  require_paths:
99
77
  - lib
100
78
  required_ruby_version: !ruby/object:Gem::Requirement
101
- none: false
102
79
  requirements:
103
80
  - - ! '>='
104
81
  - !ruby/object:Gem::Version
105
82
  version: '0'
106
83
  required_rubygems_version: !ruby/object:Gem::Requirement
107
- none: false
108
84
  requirements:
109
- - - ! '>='
85
+ - - ! '>'
110
86
  - !ruby/object:Gem::Version
111
- version: '0'
87
+ version: 1.3.1
112
88
  requirements: []
113
89
  rubyforge_project:
114
- rubygems_version: 1.8.23
90
+ rubygems_version: 2.0.3
115
91
  signing_key:
116
- specification_version: 3
92
+ specification_version: 4
117
93
  summary: Run external commands on Unix or Windows
118
94
  test_files: []