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

Methods included from CLI::Helpers

#command_name, #raise_if_command_failed!, #utility

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.



64
65
66
67
68
# File 'lib/backup/pipeline.rb', line 64

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, and the last command added to the pipeline should not attempt to write to STDOUT, as this will raise an Exception.

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



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

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)


54
55
56
# File 'lib/backup/pipeline.rb', line 54

def success?
  @errors.empty?
end