Class: Backup::Pipeline

Inherits:
Object
  • Object
show all
Includes:
CLI::Helpers
Defined in:
lib/backup/pipeline.rb

Constant Summary

Constants included from CLI::Helpers

CLI::Helpers::UTILITY

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePipeline

Returns a new instance of Pipeline.



9
10
11
12
13
# File 'lib/backup/pipeline.rb', line 9

def initialize
  @commands = []
  @errors = []
  @stderr = ''
end

Instance Attribute Details

#errorsObject (readonly)

Returns the value of attribute errors.



7
8
9
# File 'lib/backup/pipeline.rb', line 7

def errors
  @errors
end

#stderrObject (readonly)

Returns the value of attribute stderr.



7
8
9
# File 'lib/backup/pipeline.rb', line 7

def stderr
  @stderr
end

Instance Method Details

#<<(command) ⇒ Object

Adds a command to be executed in the pipeline. Each command will be run in the order in which it was added, with it’s output being piped to the next command.



19
20
21
# File 'lib/backup/pipeline.rb', line 19

def <<(command)
  @commands << command
end

#error_messagesObject

Returns a multi-line String, reporting all STDERR messages received from the commands in the pipeline (if any), along with the SystemCallError (Errno) message for each command which had a non-zero exit status.

Each error is wrapped by Backup::Errors to provide formatting.



66
67
68
69
70
# File 'lib/backup/pipeline.rb', line 66

def error_messages
  @error_messages ||= (stderr_messages || '') +
      "The following system errors were returned:\n" +
      @errors.map {|err| Errors::Error.wrap(err).message }.join("\n")
end

#runObject

Runs the command line from β€˜#pipeline` and collects STDOUT/STDERR. STDOUT is then parsed to determine the exit status of each command. For each command with a non-zero exit status, a SystemCallError is created and added to @errors. All STDERR output is set in @stderr.

Note that there is no accumulated STDOUT from the commands themselves. Also, the last command should not attempt to write to STDOUT. Any output on STDOUT from the final command will be sent to STDERR. This in itself will not cause #run to fail, but will log warnings when all commands exit with non-zero status.

Use β€˜#success?` to determine if all commands in the pipeline succeeded. If `#success?` returns `false`, use `#error_messages` to get an error report.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/backup/pipeline.rb', line 37

def run
  Open4.popen4(pipeline) do |pid, stdin, stdout, stderr|
    pipestatus = stdout.read.gsub("\n", '').split(':').sort
    pipestatus.each do |status|
      index, exitstatus = status.split('|').map(&:to_i)
      if exitstatus > 0
        command = command_name(@commands[index])
        @errors << SystemCallError.new(
          "'#{ command }' returned exit code: #{ exitstatus }", exitstatus
        )
      end
    end
    @stderr = stderr.read.strip
  end
  Logger.warn(stderr_messages) if success? && stderr_messages
rescue Exception => e
  raise Errors::Pipeline::ExecutionError.wrap(e)
end

#success?Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/backup/pipeline.rb', line 56

def success?
  @errors.empty?
end