Class: Dash::Build::Report

Inherits:
Object
  • Object
show all
Defined in:
lib/dash/build/report.rb

Overview

What the build actually spent its time on, derived from the buildx progress stream.

"Steps" here means the operator's own Dockerfile steps — the vertices buildx numbered [stage k/m]. BuildKit's own bookkeeping (booting, auth tokens, metadata lookups) is kept in steps because it is still time the build took, but it is never counted as a step the operator wrote.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(steps: [], push_seconds: 0.0) ⇒ Report

Returns a new instance of Report.



19
20
21
22
# File 'lib/dash/build/report.rb', line 19

def initialize(steps: [], push_seconds: 0.0)
  @steps = steps
  @push_seconds = push_seconds
end

Instance Attribute Details

#push_seconds ⇒ Object (readonly)

Returns the value of attribute push_seconds.



8
9
10
# File 'lib/dash/build/report.rb', line 8

def push_seconds
  @push_seconds
end

#steps ⇒ Object (readonly)

Returns the value of attribute steps.



8
9
10
# File 'lib/dash/build/report.rb', line 8

def steps
  @steps
end

Class Method Details

.from_h(hash) ⇒ Object

Rebuilds a report from what #to_h exported. Only the steps and the push are restored: every other number in the export is derived from them, so recomputing keeps a hand-edited file from claiming a total its own steps do not add up to.



13
14
15
16
17
# File 'lib/dash/build/report.rb', line 13

def self.from_h(hash)
  hash = hash.transform_keys(&:to_sym)

  new steps: Array(hash[:steps]).map { |step| Dash::Build::Step.from_h(step) }, push_seconds: hash[:push_seconds].to_f
end

Instance Method Details

#any? ⇒ Boolean

Returns:

  • (Boolean)


24
25
26
# File 'lib/dash/build/report.rb', line 24

def any?
  steps.any?
end

#cache_export_seconds ⇒ Object



66
67
68
# File 'lib/dash/build/report.rb', line 66

def cache_export_seconds
  seconds_for(:cache_export)
end

#cached_steps ⇒ Object



36
37
38
# File 'lib/dash/build/report.rb', line 36

def cached_steps
  dockerfile_steps.select(&:cached)
end

#context_bytes ⇒ Object



54
55
56
# File 'lib/dash/build/report.rb', line 54

def context_bytes
  context_step&.bytes
end

#context_seconds ⇒ Object



58
59
60
# File 'lib/dash/build/report.rb', line 58

def context_seconds
  context_step&.seconds
end

#context_step ⇒ Object



50
51
52
# File 'lib/dash/build/report.rb', line 50

def context_step
  steps.find { |step| step.kind == :context }
end

#dockerfile_steps ⇒ Object



28
29
30
# File 'lib/dash/build/report.rb', line 28

def dockerfile_steps
  steps.select(&:dockerfile_step?)
end

#errors ⇒ Object



74
75
76
# File 'lib/dash/build/report.rb', line 74

def errors
  steps.select(&:error)
end

#export_seconds ⇒ Object



62
63
64
# File 'lib/dash/build/report.rb', line 62

def export_seconds
  seconds_for(:export)
end

#failed_steps ⇒ Object

The errors worth putting in front of an operator. BuildKit reports a cache-import miss as an ERROR on its own vertex — the first build against a fresh cache always has one — and a row saying "error" for something that did not fail the build teaches people to ignore the column.



82
83
84
# File 'lib/dash/build/report.rb', line 82

def failed_steps
  errors.select { |step| step.dockerfile_step? || step.kind == :export }
end

#instruction_steps ⇒ Object



32
33
34
# File 'lib/dash/build/report.rb', line 32

def instruction_steps
  steps.select { |step| step.kind == :instruction }
end

#slowest(count) ⇒ Object

The rows worth printing: the operator's own instructions, longest first. A FROM or a metadata lookup is not something they can speed up by editing the Dockerfile.



46
47
48
# File 'lib/dash/build/report.rb', line 46

def slowest(count)
  instruction_steps.reject(&:cached).sort_by { |step| -step.seconds.to_f }.first(count)
end

#to_h ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/dash/build/report.rb', line 86

def to_h
  {
    context_bytes: context_bytes,
    context_seconds: context_seconds,
    cached_steps: cached_steps.size,
    total_steps: dockerfile_steps.size,
    export_seconds: export_seconds,
    cache_export_seconds: cache_export_seconds,
    push_seconds: push_seconds,
    total_step_seconds: total_step_seconds,
    steps: steps.map(&:to_h)
  }
end

#total_step_seconds ⇒ Object



70
71
72
# File 'lib/dash/build/report.rb', line 70

def total_step_seconds
  steps.sum { |step| step.seconds.to_f }
end

#uncached_steps ⇒ Object



40
41
42
# File 'lib/dash/build/report.rb', line 40

def uncached_steps
  dockerfile_steps.reject(&:cached)
end