Class: CC::Analyzer::Container

Inherits:
Object
  • Object
show all
Defined in:
lib/cc/analyzer/container.rb

Defined Under Namespace

Classes: ContainerData

Constant Summary collapse

ImageRequired =
Class.new(StandardError)
DEFAULT_TIMEOUT =

15m

15 * 60

Instance Method Summary collapse

Constructor Details

#initialize(image:, name:, command: nil, listener: ContainerListener.new, timeout: DEFAULT_TIMEOUT) ⇒ Container

Returns a new instance of Container.

Raises:



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/cc/analyzer/container.rb', line 17

def initialize(
  image:,
  name:,
  command: nil,
  listener: ContainerListener.new,
  timeout: DEFAULT_TIMEOUT
)
  raise ImageRequired if image.blank?
  @image = image
  @name = name
  @command = command
  @listener = listener
  @timeout = timeout
  @output_delimeter = "\n"
  @on_output = ->(*) { }
  @timed_out = false
  @stderr_io = StringIO.new
end

Instance Method Details

#on_output(delimeter = "\n", &block) ⇒ Object



36
37
38
39
# File 'lib/cc/analyzer/container.rb', line 36

def on_output(delimeter = "\n", &block)
  @output_delimeter = delimeter
  @on_output = block
end

#run(options = []) ⇒ Object



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
67
# File 'lib/cc/analyzer/container.rb', line 41

def run(options = [])
  started = Time.now
  @listener.started(container_data)

  @pid, _, out, err = POSIX::Spawn.popen4(*docker_run_command(options))

  t_out = read_stdout(out)
  t_err = read_stderr(err)
  t_timeout = timeout_thread(@pid)

  _, status = Process.waitpid2(@pid)
  if @timed_out
    @listener.timed_out(container_data(duration: @timeout))
  else
    duration = ((Time.now - started) * 1000).round
    @listener.finished(container_data(duration: duration, status: status))
  end
ensure
  t_timeout.kill if t_timeout
  if @timed_out
    t_out.kill if t_out
    t_err.kill if t_err
  else
    t_out.join if t_out
    t_err.join if t_err
  end
end

#stopObject



69
70
71
72
73
74
75
76
# File 'lib/cc/analyzer/container.rb', line 69

def stop
  # Prevents the processing of more output after first error
  @on_output = ->(*) { }

  Process.kill("TERM", @pid) if @pid
rescue Errno::ESRCH
  Analyzer.statsd.increment("container.kill_process_rescue")
end