Module: EY::Backup::Spawner
- Extended by:
- Spawner, Forwardable
- Defined in:
- lib/ey_backup/spawner.rb
Constant Summary collapse
- CHUNK_SIZE =
4096
Instance Method Summary collapse
- #ioify(stdout, stdin, stderr, &block) ⇒ Object
- #run(command, db = nil) ⇒ Object
- #runs?(command, db) ⇒ Boolean
- #spawn(command, stdout = nil, stdin = nil, stderr = logger.stderr) ⇒ Object
Instance Method Details
#ioify(stdout, stdin, stderr, &block) ⇒ Object
68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/ey_backup/spawner.rb', line 68 def ioify(stdout, stdin, stderr, &block) if String === stdin File.open(stdin, 'r') do |f| ioify(stdout, f, stderr, &block) end elsif String === stdout File.open(stdout, 'w') do |f| ioify(f, stdin, stderr, &block) end else yield stdout, stdin, stderr end end |
#run(command, db = nil) ⇒ Object
23 24 25 26 27 |
# File 'lib/ey_backup/spawner.rb', line 23 def run(command, db = nil) unless runs?(command, db) raise "Failed to run backup command." end end |
#runs?(command, db) ⇒ Boolean
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/ey_backup/spawner.rb', line 29 def runs?(command, db) # This is to detect failures anywhere in the pipeline. wrapper = <<-EOT status=0 #{command} status=$? if [ $status -gt 0 ]; then exit 1; fi EOT escaped_command = Shellwords.escape(wrapper) verbose "Running command: #{command}" pid, stdin, stdout, stderr = Open4.popen4("bash -o pipefail -c #{escaped_command}") pid, status = Process::waitpid2(pid) verbose "stdout: #{stdout.read}" verbose "stderr: #{stderr.read}" verbose "status: #{status}" if ! status.success? dumperr = File.exists?("/tmp/eybackup.#{pid}.dumperr") ? File.read("/tmp/eybackup.#{pid}.dumperr") : status err_msg = "DB dump failed. The error returned was: #{dumperr}" verbose "#{db} backup failed: #{err_msg}" error(err_msg, db) end # Clean up: # This whole error output thing is hideous. # We need the errors, but as we're dealing with a pipeline we # need to capture them separately rather than send them as # input to the next process. We construct the backup command # in the backup engine but only know the pid of the resulting # backup here. Ugh. system("rm /tmp/eybackup.#{pid}.dumperr") if File.exists?("/tmp/eybackup.#{pid}.dumperr") status.success? end |
#spawn(command, stdout = nil, stdin = nil, stderr = logger.stderr) ⇒ Object
13 14 15 16 17 18 19 20 21 |
# File 'lib/ey_backup/spawner.rb', line 13 def spawn(command, stdout = nil, stdin = nil, stderr = logger.stderr) ioify(stdout, stdin, stderr) do |o, i, e| ios = {:stderr => e} ios[:stdout] = o if o ios[:stdin] = i if i result = Open4.spawn([command], ios) end end |