Module: EY::Backup::Spawner

Extended by:
Spawner, Forwardable
Included in:
Engine, GZipper, Spawner, Splitter
Defined in:
lib/ey_backup/spawner.rb

Constant Summary collapse

CHUNK_SIZE =
4096

Instance Method Summary collapse

Instance Method Details

#ioify(stdout, stdin, stderr, &block) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/ey_backup/spawner.rb', line 65

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

Returns:

  • (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
# File 'lib/ey_backup/spawner.rb', line 29

def runs?(command, db)
  # This is to detect failures anywhere in the pipeline.
  wrapper = "    status=0\n    \#{command}\n    status=$?\n\n    if [ $status -gt 0 ]; then exit 1; fi\n  EOT\n\n  escaped_command = Shellwords.escape(wrapper)\n\n  verbose \"Running command: \#{command}\" \n  pid, stdin, stdout, stderr = Open4.popen4(\"bash -o pipefail -c \#{escaped_command}\")\n  pid, status = Process::waitpid2(pid)\n  \n  verbose \"status: \#{status}\"\n  \n  if ! status.success?\n    dumperr = File.exists?(\"/tmp/eybackup.\#{pid}.dumperr\") ? File.read(\"/tmp/eybackup.\#{pid}.dumperr\") : \"\#{status}: \#{stderr.read.chomp}: \#{stdout.read.chomp}\"\n    err_msg = \"\#{db} backup failed! The error returned was: \#{dumperr}\"\n    error(err_msg, db)\n  end\n\n  # Clean up:\n  # This whole error output thing is hideous.\n  # We need the errors, but as we're dealing with a pipeline we\n  # need to capture them separately rather than send them as\n  # input to the next process. We construct the backup command\n  # in the backup engine but only know the pid of the resulting\n  # backup here. Ugh.\n  system(\"rm /tmp/eybackup.\#{pid}.dumperr\") if File.exists?(\"/tmp/eybackup.\#{pid}.dumperr\")\n\n  status.success?\nend\n"

#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