right_scraper 5.0.1 → 5.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  #--
2
- # Copyright: Copyright (c) 2010-2013 RightScale, Inc.
2
+ # Copyright: Copyright (c) 2016 RightScale, Inc.
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -24,20 +24,10 @@
24
24
  # ancestor
25
25
  require 'right_scraper/scanners'
26
26
 
27
- require 'json'
28
-
29
27
  module RightScraper::Scanners
30
28
 
31
- # Load workflow metadata from a filesystem.
32
- class WorkflowMetadata < ::RightScraper::Scanners::Base
33
- # Begin a scan for the given workflow.
34
- #
35
- # === Parameters
36
- # workflow(RightScraper::Resources::Workflow):: workflow to scan
37
- def begin(workflow)
38
- @workflow = workflow
39
- @metadata_filename = File.basename(workflow.metadata_path)
40
- end
29
+ # Loads existing cookbook metadata from a filesystem.
30
+ class CookbookMetadataReadOnly < CookbookMetadata
41
31
 
42
32
  # Notice a file during scanning.
43
33
  #
@@ -46,27 +36,38 @@ module RightScraper::Scanners
46
36
  # not always be necessary to read the data.
47
37
  #
48
38
  # === Parameters
49
- # relative_position(String):: relative pathname for the file from root of workflow
50
- def notice(relative_position)
51
- if relative_position == @metadata_filename
52
- @logger.operation(:metadata_parsing) do
53
- @workflow.metadata = JSON.parse(yield)
54
- end
39
+ # relative_position(String):: relative pathname for the file from root of cookbook
40
+ def notice(relative_position, &blk)
41
+ case relative_position
42
+ when JSON_METADATA
43
+ # preferred over RUBY_METADATA.
44
+ @read_blk = blk
45
+ when RUBY_METADATA
46
+ # defer to any JSON_METADATA, which we hope refers to the same info.
47
+ @read_blk ||= self.method(:generated_metadata_json_readonly)
55
48
  end
49
+ true
56
50
  end
57
51
 
58
- # Notice a directory during scanning. Since the workflow definition and
59
- # metadata live in the root directory we don't need to recurse,
60
- # but we do need to go into the first directory (identified by
61
- # +relative_position+ being +nil+).
62
- #
63
- # === Parameters
64
- # relative_position(String):: relative pathname for the directory from root of workflow
52
+ private
53
+
54
+ # Reads the existing generated 'metadata.json' or else fails.
65
55
  #
66
56
  # === Returns
67
- # Boolean:: should the scanning recurse into the directory
68
- def notice_dir(relative_position)
69
- relative_position == nil
57
+ # @return [String] metadata JSON text
58
+ def generated_metadata_json_readonly
59
+ @logger.operation(:metadata_readonly) do
60
+ # path constants
61
+ freed_metadata_dir = (@cookbook.pos == '.' && freed_dir) || ::File.join(freed_dir, @cookbook.pos)
62
+ freed_metadata_json_path = ::File.join(freed_metadata_dir, JSON_METADATA)
63
+
64
+ # in the multi-pass case we will run this scanner only on the second
65
+ # and any subsequent passed, which are outside of containment. the
66
+ # metadata must have already been generated at this point or else it
67
+ # should be considered an internal error.
68
+ return ::File.read(freed_metadata_json_path)
69
+ end
70
70
  end
71
- end
72
- end
71
+
72
+ end # CookbookMetadataReadOnly
73
+ end # RightScraper::Scanners
@@ -26,7 +26,7 @@ require 'right_scraper/scrapers'
26
26
 
27
27
  module RightScraper::Scrapers
28
28
 
29
- class ScraperError < Exception; end
29
+ class ScraperError < ::RightScraper::Error; end
30
30
 
31
31
  # Base class for all scrapers. Subclasses should override
32
32
  # #find_next which instantiates the resource from the file system.
@@ -1,5 +1,5 @@
1
1
  #-- -*- mode: ruby; encoding: utf-8 -*-
2
- # Copyright: Copyright (c) 2011 RightScale, Inc.
2
+ # Copyright: Copyright (c) 2011-2016 RightScale, Inc.
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -23,7 +23,7 @@
23
23
 
24
24
  module RightScraper
25
25
  # for gemspec, etc.
26
- GEM_VERSION = '5.0.1'
26
+ GEM_VERSION = '5.1.1'
27
27
 
28
28
  # (Fixnum) protocol versioning scheme; prepended to hashes to
29
29
  # prevent collisions.
@@ -37,6 +37,7 @@ require ::File.expand_path('../lib/right_scraper/version', __FILE__)
37
37
  spec.required_ruby_version = '>= 2.1'
38
38
  spec.rubyforge_project = %q{right_scraper}
39
39
  spec.require_path = 'lib'
40
+ spec.executables = ::Dir.glob("bin/*").map { |p| ::File.basename(p) }
40
41
 
41
42
  spec.add_dependency('right_aws', '>= 2.0')
42
43
  spec.add_dependency('right_git')
@@ -58,7 +59,7 @@ will analyze the repository content and instantiate "resources" as a result. Cur
58
59
  supported resources are Chef cookbooks and RightScale workflow definitions.
59
60
  EOF
60
61
 
61
- candidates = ::Dir.glob("lib/**/*") +
62
+ candidates = ::Dir.glob("{bin,scripts,lib/**}/*") +
62
63
  %w(LICENSE README.rdoc right_scraper.gemspec)
63
64
  spec.files = candidates.sort
64
65
  end
@@ -1,5 +1,6 @@
1
+ #!/usr/bin/env ruby
1
2
  #--
2
- # Copyright: Copyright (c) 2010-2013 RightScale, Inc.
3
+ # Copyright: Copyright (c) 2016 RightScale, Inc.
3
4
  #
4
5
  # Permission is hereby granted, free of charge, to any person obtaining
5
6
  # a copy of this software and associated documentation files (the
@@ -21,34 +22,21 @@
21
22
  # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23
  #++
23
24
 
24
- # ancestor
25
- require 'right_scraper/resources'
26
-
27
- module RightScraper::Resources
28
-
29
- class Workflow < ::RightScraper::Resources::Base
30
-
31
- METADATA_EXT = '.meta'
32
- DEFINITION_EXT = '.def'
33
-
34
- # Relative path to definition file
35
- # @pos must be set before this can be called
36
- #
37
- # === Return
38
- # path(String):: Path to definition file
39
- def definition_path
40
- path = @pos
41
- end
42
-
43
- # Relative path to metadata file
44
- # @pos must be set before this can be called
45
- #
46
- # === Return
47
- # path(String):: Path to metadata file
48
- def metadata_path
49
- path = @pos.chomp(File.extname(@pos)) + METADATA_EXT if @pos
50
- end
25
+ def warn(*args)
26
+ # eliminate ruby/gem warnings from output
27
+ end
51
28
 
52
- end
29
+ require 'rubygems'
30
+ require 'chef'
31
+ require 'chef/knife/cookbook_metadata'
53
32
 
33
+ if ::ARGV.size != 1
34
+ $stderr.puts "Usage: #{::File.basename(__FILE__)} <cookbook_dir>"
35
+ exit 1
54
36
  end
37
+
38
+ cookbook_dir = ARGV.pop
39
+ knife_metadata = ::Chef::Knife::CookbookMetadata.new
40
+ knife_metadata.name_args = [::File.basename(cookbook_dir)]
41
+ knife_metadata.config[:cookbook_path] = ::File.dirname(cookbook_dir)
42
+ knife_metadata.run
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ STDERR.puts "Attempted to use credentials that require passwords; bailing"
3
+ exit 1
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: right_scraper
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.0.1
4
+ version: 5.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raphael Simon
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-03-09 00:00:00.000000000 Z
13
+ date: 2016-03-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: right_aws
@@ -78,13 +78,17 @@ description: |
78
78
  will analyze the repository content and instantiate "resources" as a result. Currently
79
79
  supported resources are Chef cookbooks and RightScale workflow definitions.
80
80
  email: support@rightscale.com
81
- executables: []
81
+ executables:
82
+ - right_scraper-retrieve
83
+ - right_scraper-scan
82
84
  extensions: []
83
85
  extra_rdoc_files:
84
86
  - README.rdoc
85
87
  files:
86
88
  - LICENSE
87
89
  - README.rdoc
90
+ - bin/right_scraper-retrieve
91
+ - bin/right_scraper-scan
88
92
  - lib/right_scraper.rb
89
93
  - lib/right_scraper/builders.rb
90
94
  - lib/right_scraper/builders/base.rb
@@ -98,7 +102,6 @@ files:
98
102
  - lib/right_scraper/processes/shell.rb
99
103
  - lib/right_scraper/processes/ssh_agent.rb
100
104
  - lib/right_scraper/processes/svn_client.rb
101
- - lib/right_scraper/processes/warden.rb
102
105
  - lib/right_scraper/registered_base.rb
103
106
  - lib/right_scraper/repositories.rb
104
107
  - lib/right_scraper/repositories/base.rb
@@ -108,7 +111,6 @@ files:
108
111
  - lib/right_scraper/resources.rb
109
112
  - lib/right_scraper/resources/base.rb
110
113
  - lib/right_scraper/resources/cookbook.rb
111
- - lib/right_scraper/resources/workflow.rb
112
114
  - lib/right_scraper/retrievers.rb
113
115
  - lib/right_scraper/retrievers/base.rb
114
116
  - lib/right_scraper/retrievers/checkout_base.rb
@@ -117,19 +119,19 @@ files:
117
119
  - lib/right_scraper/retrievers/svn.rb
118
120
  - lib/right_scraper/scanners.rb
119
121
  - lib/right_scraper/scanners/base.rb
122
+ - lib/right_scraper/scanners/cookbook_filename_scanner.rb
120
123
  - lib/right_scraper/scanners/cookbook_manifest.rb
121
124
  - lib/right_scraper/scanners/cookbook_metadata.rb
125
+ - lib/right_scraper/scanners/cookbook_metadata_readonly.rb
122
126
  - lib/right_scraper/scanners/cookbook_s3_upload.rb
123
127
  - lib/right_scraper/scanners/union.rb
124
- - lib/right_scraper/scanners/workflow_manifest.rb
125
- - lib/right_scraper/scanners/workflow_metadata.rb
126
- - lib/right_scraper/scanners/workflow_s3_upload.rb
127
128
  - lib/right_scraper/scrapers.rb
128
129
  - lib/right_scraper/scrapers/base.rb
129
130
  - lib/right_scraper/scrapers/cookbook.rb
130
- - lib/right_scraper/scrapers/workflow.rb
131
131
  - lib/right_scraper/version.rb
132
132
  - right_scraper.gemspec
133
+ - scripts/knife_metadata.rb
134
+ - scripts/stub_ssh_askpass
133
135
  homepage: https://github.com/rightscale/right_scraper
134
136
  licenses: []
135
137
  metadata: {}
@@ -1,358 +0,0 @@
1
- #--
2
- # Copyright: Copyright (c) 2013 RightScale, Inc.
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # 'Software'), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18
- # IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19
- # CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20
- # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21
- # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
- #++
23
-
24
- # ancestor
25
- require 'right_scraper/processes'
26
-
27
- require 'fileutils'
28
- require 'right_popen'
29
- require 'right_popen/safe_output_buffer'
30
- require 'tmpdir'
31
-
32
- module RightScraper
33
- module Processes
34
- class Warden
35
-
36
- DEFAULT_RVM_HOME = '/usr/local/rvm'
37
- DEFAULT_WARDEN_HOME = '/opt/warden'
38
-
39
- RELATIVE_SCRIPTS_RVM_PATH = 'scripts/rvm'
40
-
41
- # TEAL FIX: dynamically discover highest rvm-installed ruby 1.9 build?
42
- DEFAULT_RVM_RUBY_VERSION = 'ruby-1.9.3-p448'
43
-
44
- WARDEN_SERVICE_SUBDIR_NAME = 'warden'
45
- RELATIVE_WARDEN_SCRIPT_PATH = 'bin/warden'
46
-
47
- WARDEN_COMMAND_TIMEOUT = 60 # max seconds to spawn, link, etc.
48
-
49
- DEFAULT_OPTIONS = {
50
- :warden_home => DEFAULT_WARDEN_HOME,
51
- :rvm_home => DEFAULT_RVM_HOME,
52
- :rvm_ruby_version => DEFAULT_RVM_RUBY_VERSION
53
- }
54
-
55
- # marshalling
56
- class LinkResult
57
- attr_reader :exit_status, :stdout, :stderr
58
-
59
- def initialize(link_result)
60
- @exit_status = link_result['exit_status'].to_i rescue 1
61
- @stdout = link_result['stdout'].to_s
62
- @stderr = link_result['stderr'].to_s
63
- end
64
-
65
- def succeeded?
66
- 0 == exit_status
67
- end
68
- end
69
-
70
- # exceptions
71
- class StateError < Exception; end
72
- class WardenError < Exception; end
73
-
74
- class LinkError < Exception
75
- attr_reader :link_result
76
-
77
- def initialize(message, link_result)
78
- super(message)
79
- @link_result = link_result
80
- end
81
- end
82
-
83
- def initialize(options = {})
84
- options = DEFAULT_OPTIONS.merge(options)
85
- @warden_home = options[:warden_home]
86
- @rvm_home = options[:rvm_home]
87
- unless @rvm_ruby_version = options[:rvm_ruby_version]
88
- raise ArgumentError.new('options[:rvm_ruby_version] is required')
89
- end
90
-
91
- # warden paths
92
- unless @warden_home && ::File.directory?(@warden_home)
93
- raise ArgumentError.new('options[:warden_home] is required')
94
- end
95
- unless @rvm_home && ::File.directory?(@rvm_home)
96
- raise ArgumentError.new('options[:rvm_home] is required')
97
- end
98
- @warden_server_dir = ::File.join(@warden_home, WARDEN_SERVICE_SUBDIR_NAME)
99
- @bin_warden_path = ::File.join(@warden_server_dir, RELATIVE_WARDEN_SCRIPT_PATH)
100
- unless File.file?(@bin_warden_path)
101
- raise StateError, "Warden CLI script cannot be found at #{@bin_warden_path.inspect}"
102
- end
103
-
104
- # rvm paths
105
- @scripts_rvm_path = ::File.join(@rvm_home, RELATIVE_SCRIPTS_RVM_PATH)
106
- unless File.file?(@scripts_rvm_path)
107
- raise StateError, "RVM setup script cannot be found at #{@scripts_rvm_path.inspect}"
108
- end
109
-
110
- # build the jail.
111
- @handle = send('create')['handle']
112
- raise StateError, 'handle is invalid' unless @handle
113
- end
114
-
115
- # Runs the script given by container-relative path. Optionally copies
116
- # files in/out before/after script execution.
117
- #
118
- # === Parameters
119
- # @param [String|Array] cmds to execute
120
- # @param [String|Array] copy_in file(s) to copy into jail (using same path on both sides) or nil or empty
121
- # @param [Hash] copy_out files as map of jail source path to host destination path or empty or nil
122
- #
123
- # === Return
124
- # @return [String] stdout text
125
- #
126
- # === Raise
127
- # @raise [StateError] for invalid state
128
- # @raise [LinkError] for link (to script output) failure
129
- # @raise [WardenError] for warden failure
130
- def run_command_in_jail(cmds, copy_in = nil, copy_out = nil)
131
- cmds = Array(cmds)
132
- raise ArgumentError, 'cmds is required' if cmds.empty?
133
- raise StateError, 'handle is invalid' unless @handle
134
-
135
- # copy any files in before running commands.
136
- copy_in = Array(copy_in)
137
- send_copy_in_cmds(copy_in) if !copy_in.empty?
138
-
139
- # note that appending --privileged will run script as root, but we have
140
- # no use case for running scripts as root at this time.
141
- output = []
142
- cmds.each do |cmd|
143
- job_id = send("spawn --handle #{@handle} --script #{cmd.inspect}")['job_id']
144
- link_result = LinkResult.new(send("link --handle #{@handle} --job_id #{job_id}"))
145
- if link_result.succeeded?
146
- output << link_result.stdout
147
- else
148
- raise LinkError.new('Script failed running in isolation.', link_result)
149
- end
150
- end
151
-
152
- # copy any files out after command(s) succeeded.
153
- if copy_out && !copy_out.empty?
154
- copy_out_cmds = copy_out.inject([]) do |result, (src_path, dst_path)|
155
- # create output directories because warden will only copy files.
156
- parent_dir = ::File.dirname(dst_path)
157
- ::FileUtils.mkdir_p(parent_dir)
158
- result << "copy_out --handle #{@handle} --src_path #{src_path.inspect} --dst_path #{dst_path.inspect}"
159
- result
160
- end
161
- send(copy_out_cmds)
162
- end
163
-
164
- return output.join("\n")
165
- end
166
-
167
- def cleanup
168
- raise StateError, 'handle is invalid' unless @handle
169
- lay_to_rest
170
- send("destroy --handle #{@handle}")
171
- ensure
172
- @handle = nil
173
- end
174
-
175
- private
176
-
177
- def create_uuid
178
- (0..15).to_a.map{|a| rand(16).to_s(16)}.join
179
- end
180
-
181
- # warden doesn't create directories on copy_in (or _out) so we need to
182
- # generate a script and execute it before invoking copy_in.
183
- #
184
- # @param [Array] copy_in as array of files to copy into jail
185
- def send_copy_in_cmds(copy_in)
186
- mkdir_cmds = copy_in.
187
- map { |dst_path| ::File.dirname(dst_path) }.uniq.sort.
188
- map { |parent_dir| "mkdir -p #{parent_dir}" }
189
- shell_script = <<EOS
190
- #!/bin/bash
191
- rm $0 # this script will self-destruct
192
- #{mkdir_cmds.join(" &&\n")}
193
- EOS
194
- mkdir_script_name = "mkdir_script_#{create_uuid}.sh"
195
-
196
- job_id = nil
197
- ::Dir.mktmpdir do |tmpdir|
198
- mkdir_script_path = ::File.join(tmpdir, mkdir_script_name)
199
- ::File.open(mkdir_script_path, 'w') { |f| f.puts shell_script }
200
- create_parent_dir_cmds = [
201
- "copy_in --handle #{@handle} --src_path #{mkdir_script_path} --dst_path /tmp/mkdirs.sh",
202
- "spawn --handle #{@handle} --script '/bin/bash /tmp/mkdirs.sh'",
203
- ]
204
- job_id = send(create_parent_dir_cmds)['job_id']
205
- end
206
-
207
- link_result = LinkResult.new(send("link --handle #{@handle} --job_id #{job_id}"))
208
- if link_result.succeeded?
209
- copy_in_cmds = copy_in.inject([]) do |result, src_path|
210
- result << "copy_in --handle #{@handle} --src_path #{src_path.inspect} --dst_path #{src_path.inspect}"
211
- result
212
- end
213
- send(copy_in_cmds)
214
- else
215
- raise LinkError.new('Failed to create parent directories for files to be copied.', link_result)
216
- end
217
- true
218
- end
219
-
220
- # Sends one or more commands to warden and accumulates the stdout and
221
- # stderr from those commands.
222
- def send(warden_cmd)
223
- # warden runs in a ruby 1.9.3 environment, for which we need rvm and a
224
- # slew of fancy setup on the assumption that the current environemnt is
225
- # not that. ideally this code would run in a standalone service where
226
- # the warden-client gem could be used to simplify some of this.
227
- warden_cmds = Array(warden_cmd).map do |line|
228
- # execute bin/warden (Geronimo)
229
- "bundle exec #{RELATIVE_WARDEN_SCRIPT_PATH} -- #{line}"
230
- end
231
-
232
- shell_script = <<EOS
233
- #!/bin/bash
234
- source #{@scripts_rvm_path} 1>/dev/null &&
235
- rvm use #{@rvm_ruby_version}@global 1>/dev/null &&
236
- cd #{@warden_server_dir} 1>/dev/null &&
237
- #{warden_cmds.join(" &&\n")}
238
- EOS
239
-
240
- # ensure bundler env vars for current process don't interfere.
241
- ::Bundler.with_clean_env do
242
- ::Dir.mktmpdir do |tmpdir|
243
- @process = nil
244
- @interupted_to_close = false
245
- @stdout_buffer = []
246
- @stderr_buffer = ::RightScale::RightPopen::SafeOutputBuffer.new
247
- warden_script_path = ::File.join(tmpdir, "run_warden_#{create_uuid}.sh")
248
- ::File.open(warden_script_path, 'w') { |f| f.puts shell_script }
249
- cmd = "/bin/bash #{warden_script_path}"
250
- ::RightScale::RightPopen.popen3_sync(
251
- cmd,
252
- :target => self,
253
- :inherit_io => true, # avoid killing any rails connection
254
- :watch_handler => :watch_warden,
255
- :stderr_handler => :stderr_warden,
256
- :stdout_handler => :stdout_warden,
257
- :timeout_handler => :timeout_warden,
258
- :exit_handler => :exit_warden,
259
- :timeout_seconds => WARDEN_COMMAND_TIMEOUT)
260
- if @process
261
- @process = nil
262
- warden_output = @stdout_buffer.join
263
- if warden_output.empty?
264
- result = {}
265
- else
266
- result = parse_warden_output(warden_output)
267
- end
268
- return result
269
- else
270
- raise WardenError, 'Unable to execute warden.'
271
- end
272
- end
273
- end
274
- end
275
-
276
- # Warden outputs something that looks like YAML but also somewhat like a
277
- # Java configuration file. in any case, the output is ambiguous because it
278
- # does not escape characters and it is possible to spawn a process that
279
- # prints output text that appears to be the start of a new key. *sigh*
280
- #
281
- # all we can do here is attempt to parse the output by some simple rules
282
- # and hope for the best.
283
- #
284
- # example:
285
- # exit_status : 0
286
- # stdout : a
287
- # b
288
- # c
289
- #
290
- # stderr :
291
- # info.state : active
292
- # ...
293
- def parse_warden_output(warden_output)
294
- parsed_lines = {}
295
- current_key = nil
296
- regex = /^([a-z._]+) \: (.*)$/
297
- warden_output.lines.each do |line|
298
- if parts = regex.match(line)
299
- current_key = parts[1]
300
- parsed_lines[current_key] = [parts[2]]
301
- elsif current_key
302
- parsed_lines[current_key] << line.chomp
303
- else
304
- raise WardenError, "Unable to parse warden output:\n#{warden_output.inspect}"
305
- end
306
- end
307
- parsed_lines.inject({}) do |result, (key, value)|
308
- result[key] = value.join("\n")
309
- result
310
- end
311
- end
312
-
313
- def lay_to_rest
314
- if @process
315
- if @process.interrupt
316
- @interupted_to_close = true
317
- @process.sync_exit_with_target
318
- else
319
- @process.safe_close_io
320
- end
321
- end
322
- end
323
-
324
- def stdout_warden(data)
325
- @stdout_buffer << data
326
- end
327
-
328
- def stderr_warden(data)
329
- @stderr_buffer.safe_buffer_data(data)
330
- end
331
-
332
- def watch_warden(process)
333
- if @interupted_to_close
334
- true
335
- else
336
- @process = process
337
- end
338
- end
339
-
340
- def timeout_warden
341
- unless @interupted_to_close
342
- raise WardenError, 'Timed out waiting for warden to respond'
343
- end
344
- end
345
-
346
- def exit_warden(status)
347
- unless @interupted_to_close || status.success?
348
- raise WardenError,
349
- "Warden failed exit_status = #{status.exitstatus}:\n" +
350
- "stdout = #{@stdout_buffer.join}\n" +
351
- "stderr = #{@stderr_buffer.display_text}"
352
- end
353
- true
354
- end
355
-
356
- end # Warden
357
- end # Processes
358
- end # RightScraper