Class: SIB::Image
- Inherits:
-
Object
- Object
- SIB::Image
- Defined in:
- lib/service_image_builder/image.rb
Overview
SIB::Image represents a docker image
Instance Attribute Summary collapse
-
#image ⇒ Object
Returns the value of attribute image.
-
#repo ⇒ Object
Returns the value of attribute repo.
Class Method Summary collapse
-
.build(repo:, build_dir:, dockerfile: 'Dockerfile', labels: {}, squash: false) ⇒ Object
TODO: Fix rubocop:disable Metrics/MethodLength.
-
.import(repo:, tag:) ⇒ Object
rubocop:enable Metrics/MethodLength.
- .labels_to_json(labels) ⇒ Object
- .parse_api_response(response) ⇒ Object
Instance Method Summary collapse
-
#<=>(other) ⇒ Object
Image#<=> is a comparison operator implementation for SIB::Image.
- #commit_id ⇒ Object
- #factor_hash ⇒ Object
-
#initialize(repo:, image:) ⇒ Image
constructor
A new instance of Image.
- #labels ⇒ Object
-
#package_manifest ⇒ Object
Image#package_manifest creates a container from @image and generates the package-manifest from it TODO extract the entire factor system out into its own object After that, remove the ‘Metrics/MethodLength` cop override.
- #push_tag(tag:) ⇒ Object
- #timestamp ⇒ Object
Constructor Details
#initialize(repo:, image:) ⇒ Image
Returns a new instance of Image.
41 42 43 44 |
# File 'lib/service_image_builder/image.rb', line 41 def initialize(repo:, image:) @image = image @repo = repo end |
Instance Attribute Details
#image ⇒ Object
Returns the value of attribute image.
10 11 12 |
# File 'lib/service_image_builder/image.rb', line 10 def image @image end |
#repo ⇒ Object
Returns the value of attribute repo.
10 11 12 |
# File 'lib/service_image_builder/image.rb', line 10 def repo @repo end |
Class Method Details
.build(repo:, build_dir:, dockerfile: 'Dockerfile', labels: {}, squash: false) ⇒ Object
TODO: Fix rubocop:disable Metrics/MethodLength
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/service_image_builder/image.rb', line 14 def self.build(repo:, build_dir:, dockerfile: 'Dockerfile', labels: {}, squash: false) build_dir ||= Dir.pwd build_args = { 'dockerfile' => dockerfile, 'labels' => labels_to_json(labels), 'squash' => squash } SIB.log.info("Building #{repo} from #{Pathname.new(build_dir).join(dockerfile)}") # TODO: maybe have parse_api_response do the logging & just raise an error # when one gets detected image = Docker::Image.build_from_dir(build_dir, build_args) do |resp| parse_api_response(resp).each do |r| SIB.log.info(r['stream'].rstrip) if r.key?('stream') end end new(repo: repo, image: image) end |
.import(repo:, tag:) ⇒ Object
rubocop:enable Metrics/MethodLength
35 36 37 38 39 |
# File 'lib/service_image_builder/image.rb', line 35 def self.import(repo:, tag:) new(repo: repo, image: Docker::Image.create('fromImage' => "#{repo}:#{tag}")) rescue Docker::Error::NotFoundError nil end |
.labels_to_json(labels) ⇒ Object
106 107 108 109 110 |
# File 'lib/service_image_builder/image.rb', line 106 def labels_to_json(labels) Oj.dump(labels || {}) rescue Oj::Error => e raise ImageError, "Couldn't convert labels to json: #{e.}" end |
.parse_api_response(response) ⇒ Object
112 113 114 115 116 117 |
# File 'lib/service_image_builder/image.rb', line 112 def parse_api_response(response) response.split("\r\n").map { |r| Oj.load(r) } rescue Oj::Error => e SIB.log.error("Couldn't JSON parse api response: #{e.}") SIB.log.info("Unparseable message: #{response}") end |
Instance Method Details
#<=>(other) ⇒ Object
Image#<=> is a comparison operator implementation for SIB::Image. If the factor_hash are the same, they’re equal. Otherwise, the latest timestamp wins.
51 52 53 54 55 |
# File 'lib/service_image_builder/image.rb', line 51 def <=>(other) return 0 if factor_hash == other.factor_hash .compare_with_coercion(other.) # <=> with coercion end |
#commit_id ⇒ Object
57 58 59 |
# File 'lib/service_image_builder/image.rb', line 57 def commit_id @commit_id ||= labels.fetch('systems.slush.commit-id', nil) end |
#factor_hash ⇒ Object
61 62 63 64 65 66 |
# File 'lib/service_image_builder/image.rb', line 61 def factor_hash @factor_hash ||= Digest::SHA2.new(256).tap do |hash| hash << commit_id hash << package_manifest end.hexdigest[0..15] end |
#labels ⇒ Object
68 69 70 |
# File 'lib/service_image_builder/image.rb', line 68 def labels @labels ||= image.json['Config']['Labels'] end |
#package_manifest ⇒ Object
Image#package_manifest creates a container from @image and generates the package-manifest from it TODO extract the entire factor system out into its own object After that, remove the ‘Metrics/MethodLength` cop override
76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/service_image_builder/image.rb', line 76 def package_manifest @package_manifest ||= String.new.tap do |manifest| container = Docker::Container.create( 'Cmd' => ['/bin/bash', '-c', 'dnf list installed | sha256sum | colrm 65 > /package-manifest'], 'Image' => image.id, 'User' => 'root' ) container.tap(&:start).tap(&:wait) manifest << container.read_file('/package-manifest').chomp container.remove end end |
#push_tag(tag:) ⇒ Object
90 91 92 93 94 95 96 97 98 99 |
# File 'lib/service_image_builder/image.rb', line 90 def push_tag(tag:) image.tag(repo: repo, tag: tag) image.push(nil, tag: tag) do |msg| SIB::Image.parse_api_response(msg).each do |r| raise SIB::ImageError, r if r.key?('error') SIB.log.info(r) end end end |
#timestamp ⇒ Object
101 102 103 |
# File 'lib/service_image_builder/image.rb', line 101 def @timestamp ||= Time.parse(labels.fetch('systems.slush.timestamp', nil)) end |